Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - beginners на то и beginners.
| | | |
Чуть чуть не так [upd] 06.11.03 01:45 Число просмотров: 1271
Автор: 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++ аналоги) линкуются всегда вне зависимости от того, были подключены хедеры или нет.
|
<beginners>
|
вопрос программерам 05.11.03 17:01 [vaborg]
Автор: fly4life <Александр Кузнецов> Статус: Elderman
|
Имеется некий простенький код на С:
main()
{
printf("Hello, World!\n");
return 0;
}
Если попробовать его скомпилировать (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++ - более строгий язык и вольности с недоопределенными символами там недопустимы.
Кстати, а ты это запускать пробовал?
|
| |
хм 05.11.03 19:02
Автор: vaborg <Israel Vaborg> Статус: Elderman
|
меня что то заинтересовал пост :)
я запустил посмотрел действительно так оно и есть более того
можно попробовать любую функцию из 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
|
Итак, господа, демонстрирую вышеприведенный смертельный номер, но на языке C++. Вот листинг:
[ktirf@ktirf ~/src]$ cat no_stdio.cpp
extern int printf(const char *, ...);
int main()
{
printf("Hello world!\n");
return 0;
}
[ktirf@ktirf ~/src]$ g++ -o no_stdio no_stdio.cpp
[ktirf@ktirf ~/src]$ ./no_stdio
Hello world!
[ktirf@ktirf ~/src]$
---
Вот, собственно, и все :) Спасибо 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++ аналоги) линкуются всегда вне зависимости от того, были подключены хедеры или нет.
|
| | | |
:) 05.11.03 19:24
Автор: vaborg <Israel Vaborg> Статус: Elderman
|
> некоторые функции стандартной библиотеки 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
|
|
|
|