Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - beginners на то и beginners.
Что-то такое я видел в архиве программинга - надо будет FAQ сделать.05.11.03 17:28 Число просмотров: 1227 Автор: fly4life <Александр Кузнецов> Статус: Elderman
> Если быть кратким, то поскольку в командной строке ты явно > не указываешь язык, то gcc (который расшифровывается как > GNU Compiler Collection, а не GNU C/C++ Compiler, между > прочим) сам его определяет - в твоем случае по расширению. > Соответственно твой код воспринимается анализатором C++, а > не C (в конце концов, не от балды же ты сделал расширение > cpp ;) ). Я сейчас не могу сходу сказать, почему > пропускается printf, но не исключаю, что этот символ по > умолчанию определен и при попытке линка с умолчальными же > библиотеками (=glibc для Linux) находится и прекрасно > подставляется. C++ - более строгий язык и вольности с > недоопределенными символами там недопустимы.
Если попробовать его скомпилировать (gcc -o test test.cpp), то выдадутся следующие ошибки:
test.cpp: In function `int main ()':
test.cpp:5: `printf' undeclared (first use this function)
test.cpp:5: (Each undeclared identifier is reported only once for each
function it appears in.)
Оно и понятно, ведь 'printf' находится где-то и должно быть описано, где именно, в соответствующем хидере (stdio.h).
НО, если переименовать файл из test.cpp в test.c и скомпилировать (gcc -o test test.c), то всё проходит (читай: компилируется) нормально и даже никаких ворнингов не выдаётся!
Объясните, плзз, это...
П.С. всё проделывалось в ОС Linux
Что-то такое я видел в архиве программинга - надо будет FAQ сделать.05.11.03 17:21 Автор: Ktirf <Æ Rusakov> Статус: Elderman
Если быть кратким, то поскольку в командной строке ты явно не указываешь язык, то gcc (который расшифровывается как GNU Compiler Collection, а не GNU C/C++ Compiler, между прочим) сам его определяет - в твоем случае по расширению. Соответственно твой код воспринимается анализатором C++, а не C (в конце концов, не от балды же ты сделал расширение cpp ;) ). Я сейчас не могу сходу сказать, почему пропускается printf, но не исключаю, что этот символ по умолчанию определен и при попытке линка с умолчальными же библиотеками (=glibc для Linux) находится и прекрасно подставляется. C++ - более строгий язык и вольности с недоопределенными символами там недопустимы.
Кстати, а ты это запускать пробовал?
меня что то заинтересовал пост :)
я запустил посмотрел действительно так оно и есть более того
можно попробовать любую функцию из stdio.h без указания в заголовке биб-ки
будет работать.
Как мне кажется дело в том что формат файл ELF
http://gazette.linux.ru.net/lg84/kim.html это немного объясняет что происходит
значит в С собираются линки на биб-ки по умолчанию (видимо список этих биб-ок можно менять и не писать громадные заголовки например)
тогда как в С++ такое почему то пресекается
Вообщем я так и остался в недоумении
поправте меня если я неправ
Да ни при чем тут ELF и C/C++. При чем только GCC (update)05.11.03 19:11 Автор: Ktirf <Æ Rusakov> Статус: Elderman Отредактировано 05.11.03 19:16 Количество правок: 3
---
Вот, собственно, и все :) Спасибо vaborg за ссылку на статью, в ней на самом деле есть короткий и ясный ответ: некоторые функции стандартной библиотеки C участвуют в компоновке всегда, потому что так работает GCC (ему нужно создать функцию __libc_main_start). Не хочешь включать stdio.h - не включай, только объяви функции из него, которые используешь.
Чуть чуть не так [upd]06.11.03 01:45 Автор: amirul <Serge> Статус: The Elderman Отредактировано 06.11.03 01:47 Количество правок: 1
> Вот, собственно, и все :) Спасибо vaborg за ссылку на > статью, в ней на самом деле есть короткий и ясный ответ: > некоторые функции стандартной библиотеки C участвуют в > компоновке всегда, потому что так В корневом посте затыкается не компоновщик, а компилер. Все из-за того, что для C++ прототип обязателен перед первым использованием (в частности связано с манглянием имен, которая в свою очередь связана со строгой типизацией), а в C - нет. В последнем случае VC++ выводит более понятный ворнинг: что то типа "функция не объявлена, будем считать, что возвращает int". В код генерится выкладывание всех аргументов в стек и
call _printf
О реальных типах агрументов ничего знать не надо.
Кстати еще одно отличие C от C++, связанное со строгой типизацией. Объявление вида
int f();
В C понимается как
int f(...); - то бишь о типах агрументов ничего не известно. А в C++ как
int f(void); - функция не имеет аргументов
А в целом действительно все происходит потому, что gcc узнает язык по расширению.
-----------------
А компоновщик тут вообще ни при чем. libc (и c++ аналоги) линкуются всегда вне зависимости от того, были подключены хедеры или нет.
> некоторые функции стандартной библиотеки C участвуют в > компоновке всегда, потому что так > работает GCC (ему нужно создать функцию > __libc_main_start). Не хочешь > включать stdio.h - не включай, только объяви функции из > него, которые используешь. а где можно увидеть весь список фукнций и библиотек которые можно так заюзать и зачем это так сделано?
Хороший вопрос :)05.11.03 19:36 Автор: Ktirf <Æ Rusakov> Статус: Elderman
> > некоторые функции стандартной библиотеки C участвуют в > > компоновке всегда, потому что так > > работает GCC (ему нужно создать функцию > > __libc_main_start). Не хочешь > > включать stdio.h - не включай, только объяви функции > из > > него, которые используешь. > а где можно увидеть весь список фукнций и библиотек которые > можно так заюзать и зачем это так сделано? Думаю, что список функций можно получить, если исследовать содержимое тех трех объектников, которые упомянуты в статье. Кроме glibc я не думаю, что какие-то еще библиотеки там задействованы. Зачем сделано именно так - на этот вопрос ответить пока не могу. Думаю, что из двух вариантов: генерировать код компилятором или линковать уже готовый код по каким-то причинам был выбран второй. Автоматически получилось, что все, с чем линкуется этот готовый код, доступно для компоновки без явного указания на это. Имхо, довольно скользкая возможность, к тому же неочевидная. You should not want to use it :)
Что-то такое я видел в архиве программинга - надо будет FAQ сделать.05.11.03 17:28 Автор: fly4life <Александр Кузнецов> Статус: Elderman
> Если быть кратким, то поскольку в командной строке ты явно > не указываешь язык, то gcc (который расшифровывается как > GNU Compiler Collection, а не GNU C/C++ Compiler, между > прочим) сам его определяет - в твоем случае по расширению. > Соответственно твой код воспринимается анализатором C++, а > не C (в конце концов, не от балды же ты сделал расширение > cpp ;) ). Я сейчас не могу сходу сказать, почему > пропускается printf, но не исключаю, что этот символ по > умолчанию определен и при попытке линка с умолчальными же > библиотеками (=glibc для Linux) находится и прекрасно > подставляется. C++ - более строгий язык и вольности с > недоопределенными символами там недопустимы.
Спасибо =)
> Кстати, а ты это запускать пробовал?
Естесственно. Работает.
Короче язык С (расширение файла .с) спокойно переваривает printf, как функцию, "неважно_что" возвращающую (int) с типами аргументов, что указаны (почти "..."), в отличии от С++.05.11.03 17:27 Автор: DPP <Dmitry P. Pimenov> Статус: The Elderman Отредактировано 05.11.03 17:28 Количество правок: 2