информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Сетевые кракеры и правда о деле ЛевинаАтака на InternetЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / beginners
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - beginners на то и beginners.
Хороший вопрос :) 05.11.03 19:36  Число просмотров: 1127
Автор: Ktirf <Æ Rusakov> Статус: Elderman
<"чистая" ссылка>
> > некоторые функции стандартной библиотеки C участвуют в
> > компоновке всегда, потому что так
> > работает GCC (ему нужно создать функцию
> > __libc_main_start). Не хочешь
> > включать stdio.h - не включай, только объяви функции
> из
> > него, которые используешь.
> а где можно увидеть весь список фукнций и библиотек которые
> можно так заюзать и зачем это так сделано?
Думаю, что список функций можно получить, если исследовать содержимое тех трех объектников, которые упомянуты в статье. Кроме glibc я не думаю, что какие-то еще библиотеки там задействованы. Зачем сделано именно так - на этот вопрос ответить пока не могу. Думаю, что из двух вариантов: генерировать код компилятором или линковать уже готовый код по каким-то причинам был выбран второй. Автоматически получилось, что все, с чем линкуется этот готовый код, доступно для компоновки без явного указания на это. Имхо, довольно скользкая возможность, к тому же неочевидная. You should not want to use it :)
<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
<"чистая" ссылка>
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach