Задать вопрос
  • Как передать сткроку, которая заканичвается на: !x в качестве аргумента командной строки?

    @MrBman Автор вопроса
    CityCat4, Вы ошибаетесь, Мне прекрасно известно что это такое и с чем их едят:))
    P.S. чисто по приколу, давайте попробуйте сделать это с помощью strncpy и strncat, посмотрим что у вас из этого получится:))) - вы и вправду думаете что они это безопасные и лучшие версии strcpy и strcat?) ну-ну:))
    ПС. мои функции чисто идеологически ближе к strlcpy и strlcat
  • Как передать сткроку, которая заканичвается на: !x в качестве аргумента командной строки?

    @MrBman Автор вопроса
    jcmvbkbc, Эм .. по-моему вы меня не поняли! Имелось ввиду что ужасны strncpy и strncat.
  • Как передать сткроку, которая заканичвается на: !x в качестве аргумента командной строки?

    @MrBman Автор вопроса
    Мда .. жесть: совсем уже всё забыл:(, - Спасибо!
    ПС. Они просто ужасны, начиная от их интерфейса, и заканчивая их поведением:(
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    Дальнейшее недопонимание возникло видимо из-за того что либо я плохо понял ваши пространные разъяснения, либо вы их написали не достаточно понятно, скорее всего оба фактора сыграли.

    В будущем постараюсь исправить свой недостаток подробного (чрезмерного) многословия. В любом случае, огромное вам спасибо за оказанную помощь и потраченное время, особенно за ссылку на https://stackoverflow.com/ - Думаю это то, что мне нужно, так что буду перебираться туда, поскольку Тостер это явно не то место, где мне смогут ответить на мои извращенные вопросы:)))
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    MrBman,
    t++ это выражение, а его значение это t. В результате вычисления этого выражения получаем побочный эффект (значение самого t увеличивается на 1). Инструкция вида t++;
    означает вычислить значение выражения ради побочного эффекта (значение самого выражения просто отбрасывается)
    ++t это выражение, а его значение это t + 1. Всё остальное тоже самое как и выше.
    Другими словами, инструкции вида t++; и ++t; дают один и тот же побочный эффект, однако значения самих выражений t++ и ++t РАЗНЫЕ, а это уже оказывает влияние на то каким образом вычисляются эти выражения, когда они являются частью составного выражения.
    Например, выражение *t++
    Приоритет оператора ++ выше чем у опереатора *, а это означает следующее *(t++)
    Сперва должно быть вычислено значение выражения t++, а как было сказано выше это t, и в результате побочного эффекта значение t должно быть увеличено на 1, а это означает что нам потребуется сохранить предыдущее значение t, для последующего его использования в качестве операнда для оператора *
    Выражение *++t
    Тоже самое, *(++t), Однако значение выражения ++t это t + 1, а это означает что нам НЕ потребуется сохранять предыдущее значение t
    Именно поэтому говорят, что ++t эффективнее t++, Просто компилятор разруливает всю ситуацию и мы не видим разницы. Хотя говорят что в более дилекатных ситуациях это может оказать влияние на производительность.
    Однако, ЕСЛИ я не ошибаюсь, то в стандарте языка ничего не говорится о том когда именно должен быть сохранен результат побочного эффекта (это будет зависеть от компилятора), таким образом, например в выражении:
    t / ++t
    Нет гарантии чему будет равно значение всего этого выражения (сперва мы вычисляем значение выражения ++t)
    НО вот далее возникает закономерный вопрос: левый операнд t будет вычислен ДО того как результат побочного эффекта будет сохранен, или уже ПОСЛЕ?
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    Вы же видите по вашей же ссылке, что компилятор достаточно умный, что бы не выполнять сложение каждый раз - сложение происходит один раз:

    Эм .. по моей ссылке используется флаг оптимизации -O1.
    Я же написал: что именно ВООБЩЕ БЕЗ оптимизаций первый вариант ВСЕГДА будет лучше второго!
    P\S смысл всего вопроса изначально и был в том: Почему то что без оптимизации лучше - после оптимизации оказалось хуже? Как я понял просто компилятор тупо во втором распознал "шаблон" решения некоторой задачи так как это распространенный прием, а в первом случае не смог понять что это тот же самый шаблон! - иначе почему он не сгенерировал одинаковый код?
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    Вы ошибаетесь на счет *t++ - оно работает именно так как задумывается, а именно - возвращает значение *t, затем увеличивает на 1 адрес в t.
    Но вы правы в том, что return будет возвращать не верное значение из-за *t++, я не обратил на это внимания, согласен.

    Эм... так в чем проблема то? я же написал тоже самое:))) в пункте 3:
    3) таким образом значение всего выражения *(t++) равно *t, где как было сказано выше t это значение до увеличения на 1, ОДНАКО для тех кто будет использовать значение t ниже оно уже увеличено на 1
    Смотрите приоритеты операторов:
    https://en.cppreference.com/w/c/language/operator_...
    книга о которой я писал выше:
    https://www.amazon.com/Puzzle-Book-Alan-R-Feuer/dp...
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    res2001, Уж бог с ней с лишней операцией инкремента, Ваш код вообще не будет работать, точнее он будет делать не то что надо:)))

    1) выражение вида *t++ означет следующее *(t++)
    2) значение выражение вида t++ равно t, ОДНАКО после вычисления этого выражения значение t будет увеличено на 1 (хотя это не обязательно выполнится после вычисления этого выражения) возможно это произойдет после вычисления всего выражения *(t++) - всё завсиит от реализации компилятора
    3) таким образом значение всего выражения *(t++) равно *t, где как было сказано выше t это значение до увеличения на 1, ОДНАКО для тех кто будет использовать значение t ниже оно уже увеличено на 1
    4) а значит в последней инструкции return *s - *t;
    значение t будет не то которое нам нужно и как результат мы получим неправильный результат

    Ну, Например:
    char *s = "Hello!";
    char *t = "Hello!#";
    тогда получим что строки равны
    потому что когда мы дойдем до конца и будет сравнивать '\0' из s
    с '#' из t то мы после увеличим t на 1 и как результат тепеть t указывает также на '\0'
    и как результат получим return '\0' - '\0'
    => равны, что конечно же не так:)))

    Вот такой вот хитрый и типичный баг, когда используешь подобные выражения c побочными эффектами. В Си это целая история:)))
    Рекомендую прочитать, если интересно книжку:
    The C puzzle book by Alan R. Feuer
    эта книга просто божественна
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    Компилятор первую версию превращает во вторую

    Эм .. а разве тогда код не должен был получиться одинаковый при одном и том же флаге оптимизации? Мне просто не понятно почему он не может сообразить при флаге -O1 сделать тоже самое что он сделал со вторым вариантом при этом же флаге!
    Он не смог в первом варианте распознать "шаблон", а во втором случае смог, так как второй случай очень распространенный "прием"?
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    res2001, Если вы имеете в виду вообще без каких-либо оптимизаций, Эм .. если я правильно понимаю, то вполне логично что первый вариант лучше, посколько компилятор всегда транслирует выражение s[i] в *(s + K*i),
    где i надо умножить на размер объекта (K) (в данном случае это не важно так как K = 1 поскольку это тип char), а вот в остальных случаях надо будет еще и УМНОЖАТЬ.
    Но даже и без учета умножения во втором варианте много выражений вида s[i], а значит при вычислении таких выражений надо будет каждый раз выполнять сложение!
    P\S меня интересует именно при оптимизации
  • И снова clang: Почему (при оптимизации) реализация на указателях получилась хуже чем с использованием оператора [ ]?

    @MrBman Автор вопроса
    Кстати, посмотри интереса ради gcc -Os.

    Спасибо, за полезную информацию!
  • Как в языке С: 1) реализуется понятие "inline" функция? 2) возможно ли реализовать общее имя функции для разных типов?

    @MrBman Автор вопроса
    Василий Мельников,
    Хм ... Язык C++ насколько я понимаю появился из С, а раз в C++ подобные штуки возможны, то почему в С нельзя их реализовать хотя бы "костыльно извращённым способом"?

    P\S
    Дело тут в том, что моя конечная цель это не писать прикладные вещи. Я уже и сейчас могу их писать без проблем. Моя конечная цель это сам инструмент (компилятор и следовательно сам язык программирования в целом). Для меня, компилятор - это то самое место где и происходит вся магия и волшебство. Именно это и завораживает меня больше всего. Писать программы по сути может каждый, вот только без компилятора это по сути НЕвозможно:)))
    Яязык С для меня просто проходная, но при этом ОЧЕНЬ полезная точка на пути к моей цели.
    Язык С помогает мне понять как устроены вещи на самом деле, в отличии от других языков более высокого уровня, которые прячут всё это за разными абстракциями. (тот же С++)
  • Почему clang (x86-64 7.0.0) генерирует хуже код (в данном примере)?

    @MrBman Автор вопроса
    res2001,
    Меньшее количество инструкций не всегда говорит о том, что код лучше.

    Я уже сам убедился в том, что меньшее колличество кода на языке С не гарантирует, что компилятор сгенерирует меньше машинных инструкций. Опять же, например, когда я сравнивал OpenBSD реализацию strncat со своей, то был в шоке. Я не мог поверить, что столь, на мой взгляд разумеется, "макаронная" реализация оказалась эффективнее моей (кому интересно, можете сами посмотреть, что я имею ввиду, в исходниках OpenBSD).
    Мой вопрос, не в том какая функция будет быстрее. Мне это не интересно, так как я считаю, что это не тот вопрос на который надо отвечать в первую очередь! Меня интересует, что в моём коде так сильно повлияло на поведение компилятора clang??? - я думал, что мой код лучше:)))
    В конце концов, ведь не зря же именно такая реализация (например, у той же strncat) в OpenBSD. Человек, который это писал, точно знал, что так будет лучше! То, есть он знал некий "секрет", того, что точно будет делать компилятор.
    Вот в этом и есть главный вопрос: как быть уверенным что некий код, это хороший код? Полагаю, для этого надо самому написать компилятор или разобраться как устроен уже существующий, и по-другому никак:(((
  • Почему clang (x86-64 7.0.0) генерирует хуже код (в данном примере)?

    @MrBman Автор вопроса
    sim3x, я указал что с -O3 (да там вообще без разницы и с -O2 тоже самое)
  • Как активировать Windows 10 не обновляя с 8-ки?

    @MrBman
    Кстати, недавно была возможность получить Windows 10 Pro, даже если у вас НИКОГДА не было лицензионной Windows 7 и 8, и вы не принимали участие в Insider программе Windows 10. Смотреть здесь(пробуйте, возможно ещё работает):
    geektimes.ru/post/262978
    P.S. У меня всё прекрасно установилось, активировалось и прекрасно обновляется. Также проверял, при новой чистой установке ключ вводить не нужно, само активируется, так что полная халява:)