Pull to refresh
41
-9
Vladimir Shaleev @vladimirshaleev

User

Send message

svlasov, спасибо, уточню это в статье

TheCalligrapher

Это - совершенно не верное объяснение. Тип символьной константы здесь совершенно ни при чем.

Большое спасибо, за объяснение, как будет время, внесу необходимые правки

lrrr11 Правильно что не стали читать, не надо было и этот комментарий писать

TheCalligrapher большое спасибо за такой развернутый комментарий

Лучше такой объем опускайте под спойлер, чтобы другим читателям было удобнее читать комментарии.

Я постараюсь внести необходимые правки про функции без прототипа, чтобы текст более соответствовал действительности.

ABI позволяют передавать даже variadic аргументы в регистрах процессора.

что в статье и сказано, читайте статью внимательнее, но я согласен, что возможно стоило выразить это в более явной форме

Во-первых, то, о чем вы писали выше, это и есть "альтернативный стиль K&R"

спасибо, это я тоже поправлю, чтобы это было явно указано

Вы это все, конечно, попытались запихать в свою теорию "это всё эллипсис", но это - полная чушь.

Нет, не пытался. Но если Вы меня так поняли, значит я плохо написал

Никакого отношения к языкам С и С++ это, разумеется, не имеет. Никаких calling conventions ни в С, ни в С++ нет. Что это делает в статье про "особенности С и С++" - не ясно.

Полностью согласен, я это писал только для того чтобы дизасм объяснить для printf. Конкретно почему там не через стек толкаются параметры. А то у кого-то могли возникнуть вопросы. Но этот текст нужно либо вообще удалить из статьи, либо опустить под спойлер.

Грубейше не верно. Строковый литерал - это массив, то есть char[N] в языке С и const char[N] в C++

Что в статье и написано, читайте внимательно.

Верно, это зависит от платформы.

Я ввел в заблуждение, когда обозначил, что в x64 calling convention есть строго-оговорённое количество используемых регистров. Я доработаю этот абзац, чтобы он соответствовал действительности

Спасибо за комментарий. Да деструктор по умолчанию noexcept, как я описал в своей статье.

Ваш пример кода на gobolt это UB код

Подробнее здесь

Это потому что не смотря на то, что вы за счет noexcept(false) может развернуть стек и даже обработать исключение в некоторых случаях (которые, кстати, указаны в статье). Это не значит что он будет работать корректно во всех случаях. Если например вы будете дорабатывать такой код и у вас между созданием и уничтожение такого экземпляра появится какой-то вызов функции, который в теории может бросить исключение ваш код может перестать работать, и вообще может случиться что угодно.

Приведу пример.

Вот код https://godbolt.org/z/hnqTaE7jG. Здесь мы создаем два экземпляра двух типов. Из деструктора B вылетает исключение и он успешно разворачивает стек и ловится (за счет noexcept(false)).

Потом пришел другой программист и начал дорабатывать бизнес логику продукта в этом UB коде и добавил вызов функции после создания экземпляра B. И он это сделал абсолютно легально. Его функция в некоторых случаях может бросать исключение, что также абсолютно легально. Он написал полностью корректный C++ код.

Запустите этот доработанный код https://godbolt.org/z/3YavK5Eah и вы увидите, что он перестал работать. Вряд ли другой программист, мог знать, что Вы кидаете исключение из деструктора. И здесь прав он, его исключение должно было быть перехвачено по правилам языка C++ и обработано. Но вместо этого деструктор A не был вызван, а процесс упал.

Естественно это UB, я не могу дорабатывать и вообще никто не может дорабатывать такой код, в котором оставлены такие мины. При том такие мины бахнут на продакшене уже, в каких-то рандомных кейсах. Это поведение невозможно предсказать. Оно на данном примере ведет себя по разному как мы можем видеть, даже в рамках одного компилятора (то экспешн из деструктора поймался, то не поймался).

chanav, Вы правы, в моей статье ошибка, большое спасибо за данный комментарий!

geher, большое спасибо за комментарий про char

Можете уточнить про имена символов или, если есть такая возможность, привести дизасм C кода сбилженого под архитектуру x64 с разными колконвеншенами функций: cdecl, stdcall, fastcall и т.д., где будет видно что имена символов изменились?

Не совсем так. Наличие или отсутствие cdecl в объявлении экспортируемой функции даже для архитектуры x64 как минимум указывает на особенности ее именования в разделяемой библиотеке (dll или so).

Мне кажется это не так или я не правильно понял утверждение. На сколько я знаю, если при билде компилятор игнорирует указанный колконвешн, он и имя никак не будет декорировать согласно указанному колконвешену.

Мои обоснования такие

Потому что в имени как раз и декорируется информация о колконвешене (т.н. декорирование имен). Чтобы во время связывания кода линковщик знал как вызывать функцию и передавать в нее аргументы, а также кто должен сместить адрес стека.

Например линковщик видит символ с таким именем:

@AddSubFc@16

И он понимает из названия (по символу @), что речь идет о конвенции fastcall:

extern "C" int _fastcall AddSubFc(int i1, int i2, int i3, int i4);

Или например видит такой символ:

_AddInts@8

Линковщик понимает что речь идет о такой сигнатуре stdcall:

extern "C" int _stdcall AddInts(int i1, int i2);

Это примеры для MSVC x86.

Я к тому, что если, компилятор игнорирует указанную программистом конвенцию, тогда и имя символа он не будет менять согласно это конвенции, а оставит свою, иначе он не смог бы корректно связаться с символом.

Поправьте меня, пожалуйста, если я не прав или не правильно понял комментарий. Или просто не ясно излагаю мысли

Вы абсолютно правы в своих суждениях.

Но я никого не хотел раздражать таким введением или устанавливать правила проведения собеседований.

Это скорее было написано для красного словца. Конечно, же на каких-то собеседованиях про это спорят. Или из любопытства могут спросит, даже глубже могут копнуть, и начнется битва двух ёкодзун.

Большое спасибо, за полезный комментарий! Сразу вспомнился API libpng, в частности то как там обрабатываются ошибки с setjmp

Information

Rating
Does not participate
Registered
Activity

Specialization

Backend Developer