Re[8]: Феерия с inline в C99 и GCC 5.1
От: watchmaker  
Дата: 05.07.15 10:43
Оценка: +1
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, watchmaker, Вы писали:


К>>>Но синтаксически... сломали совместимость.

W>>Сломали совместимость с чем? Такое поведение у inline в стандарте языка было всегда

К>http://ideone.com/x4thLo — C89 — ok


И почему ты решил, что по ссылке с89? Там как раз тот самый «язык Си с лямбда-функциями и компанией».
В c89 это невалидный код. По стандарту он даже не скомпилируется.
Вот что думает gcc-4.8 -std=c89 про строчку c inline:
ll.c:3:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
 inline void foo() { printf("foo\n"); }
        ^

А вот что думает clang-3.5 -std=c89:
ll.c:3:1: error: unknown type name 'inline'
inline void foo() { printf("foo\n"); }
^


Это уже не говоря о том, что есть и куда более важное несоответствие с c89:

gcc
ll.c:8:5: error: expected expression before ‘/’ token
     // your code goes here
     ^

clang
ll.c:8:5: error: // comments are not allowed in this language 
    // your code goes here
    ^





К>Хочешь сказать, что инстанцирование &foo — это добрая воля и личная инициатива компилятора?

В с99 инстанциирования не будет по стандарту (и у компиляторов с этим нет проблем — не делать как-то всегда проще чем наоборот что-то делать).
В с89 такой код невалиден.

К>(Аналогичная ситуация со статическими членами-константами в С++ однозначно приводит к ошибке линковки).

Однозначно — слишком сильно сказано. Никто не гарантирует, что такая ситуация не приведёт. И, конечно, это нужно исправлять. Но достаточно часто не приводит из-за слишком умного оптимизатора, и забытое определение может быть обнаружено совсем не сразу.
Отредактировано 05.07.2015 11:11 watchmaker . Предыдущая версия . Еще …
Отредактировано 05.07.2015 10:52 watchmaker . Предыдущая версия .
Отредактировано 05.07.2015 10:48 watchmaker . Предыдущая версия .
Re[7]: Феерия с inline в C99 и GCC 5.1
От: Abyx Россия  
Дата: 05.07.15 11:58
Оценка:
Здравствуйте, jazzer, Вы писали:

W>>>Кстати говоря, в C++ есть механизмы, который работают точно также. Например,
W>>>class Bar {
W>>>   static const int x = 4;
W>>>};

W>>>По стандарту недостаточно написать это в .h файле, но нужно дополнительно в одном из .cpp файлов сделать инстанциирование
const int Bar::x;


A>>только если "x" ODR-used. (http://ru.stackoverflow.com/a/419547/177684)


J>Теоретически да, а практически у меня гцц в релизных билдах все собирает нормально, а дебаг-билдах требует инстанцирование.


там по ссылке на RU.SO об этом и написано.

если есть код
int f(int& arg) { return arg; }
int main() {
  return f(Bar::x);
}

то оптимизатор инлайнит код, и переменная перестает быть ODR-used.

а без оптимизаций f(Bar::x) остается, генерится код
extern dd Bar_x
...
main:
  push offset Bar_x
  call f
  ret

и линкер выдает ошибку
In Zen We Trust
Re[8]: Феерия с inline в C99 и GCC 5.1
От: Abyx Россия  
Дата: 05.07.15 12:04
Оценка:
Здравствуйте, Кодт, Вы писали:

К>http://ideone.com/x4thLo — C89 — ok

К>http://ideone.com/BjDw9c — C99 — undefined reference

лучше использовать онлайн компилятор в котором можно задать командную строку
http://coliru.stacked-crooked.com/a/2491064e67a98380

main.cpp:3:8: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'

 inline void foo() { printf("foo\n"); }
In Zen We Trust
Re[9]: Феерия с inline в C99 и GCC 5.1
От: Кодт Россия  
Дата: 05.07.15 14:12
Оценка: :))
Здравствуйте, Abyx, Вы писали:

A>лучше использовать онлайн компилятор в котором можно задать командную строку

A>http://coliru.stacked-crooked.com/a/2491064e67a98380

Ох щи! Оказывается, inline — это фича C99 и расширение GNU C89. То есть, все эти годы мы ходили по граблям...
Перекуём баги на фичи!
Re[10]: Феерия с inline в C99 и GCC 5.1
От: _NN_ www.nemerleweb.com
Дата: 06.07.15 05:28
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Abyx, Вы писали:


A>>лучше использовать онлайн компилятор в котором можно задать командную строку

A>>http://coliru.stacked-crooked.com/a/2491064e67a98380

К>Ох щи! Оказывается, inline — это фича C99 и расширение GNU C89. То есть, все эти годы мы ходили по граблям...


Хорошо хоть MS используют два подчеркивания для расширений __inline.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Феерия с inline в C99 и GCC 5.1
От: Mr.Delphist  
Дата: 06.07.15 08:16
Оценка: +2
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, Tilir, Вы писали:


T>>Не все знают, что в GCC начиная с 5.0 стандартом по умолчанию сделали C99.


A>я смотрю что не все знают что сейчас 2015 год, а не 1999

A>за 15 лет уже новые программисты родились (sic!), а вы всё не можете прочитать что там такое написано в стандарте,
A>который содержит всего 500 страниц (а не 1300 как в С++)

Ну, я бы сказал, что это из области "программистского бессознательного". Я вот при "plain C" на автомате пишу static для всех локальных функций, но про тонкости стандартов Cxx vs Cyy действительно не задумывался (в отличие от C++), в первую очередь по причине идиомы "это ж plain C, старый язык, едва ли не legacy".
Re: Феерия с inline в C99 и GCC 5.1
От: Mr.Delphist  
Дата: 06.07.15 08:19
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Hi,


T>Не все знают, что в GCC начиная с 5.0 стандартом по умолчанию сделали C99.

T>Но это является источником радости. Надеюсь этот пост убережет кого-то из тех, кто пойдет по моим следам (перевод немаленького проекта на новый компилятор).

Благодарствую за граблеописание. Ещё раз убедился, что моя подсознательная нелюбовь к явному описанию inline — не спроста
Re: Феерия с inline в C99 и GCC 5.1
От: MShura  
Дата: 06.07.15 14:31
Оценка: -1
T>Не все знают, что в GCC начиная с 5.0 стандартом по умолчанию сделали C99 (UPD: на самом деле GNU11, то есть C11 + GNU extensions)
T>Но это является источником радости. Надеюсь этот пост убережет кого-то из тех, кто пойдет по моим следам (перевод немаленького проекта на новый компилятор).

T>Итак вы берете некий код, который кажется не содержит никаких ошибок:


Как-же будет компилиться ядро линукса?
Вот "стандартный" файл fs.h

http://lxr.free-electrons.com/source/include/linux/fs.h?v=4.1#L738

"static inline" — очень много. Будут переделывать?
Re[2]: Феерия с inline в C99 и GCC 5.1
От: MShura  
Дата: 06.07.15 17:42
Оценка:
MS>"static inline" — очень много. Будут переделывать?

Каюсь не обратил внимание на то, что static решает проблему
Сам постоянно пишу static inline и уж чуть было не бросился переписывать (пока только на 4.8.2 работаю)
Re[8]: Феерия с inline в C99 и GCC 5.1
От: watchmaker  
Дата: 06.07.15 18:12
Оценка: +1
Здравствуйте, Abyx, Вы писали:

A>если есть код

A>
A>int f(int& arg) { return arg; }
A>int main() {
A>  return f(Bar::x);
A>}
A>

A>то оптимизатор инлайнит код, и переменная перестает быть ODR-used.
Ну нет. Переменная не перестаёт быть ODR-used. Это же формальное свойство — оно зависит только от текста программы, а не от используемого компилятора или его настроек оптимизации. И встраивание тут не исключение.

А собирается такая программа лишь из-за особенностей устройства линкера и компилятора. Раз по стандарту компилятор не должен следить за наличием определений для ODR-used переменных, то он и не следит. А linker игнорирует всё, на что нет внешних ссылок. Вместе две эти особенности и приводят к успешной сборке программы.

В общем, пропадает не свойство ODR-used, а ссылки внутри объектных файлов. Вот только первое — это про С++, а второе — лишь про особенности конкретной реализации. Сама же константа Bar::x как была ODR-used, так и осталась.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.