Как работает расширенная функция GNU, когда она не определена _GNU_SOURCE - PullRequest
0 голосов
/ 13 ноября 2018

Я тестирую расширенную функцию GNU, такую ​​как "wcstoq" на разных платформах. Сначала я не компилировал тестовый пример с помощью D_GNU_SOURCE ,, поэтому получил предупреждение о компиляции следующим образом:

wcstoq.c:31:12: warning: implicit declaration of function 'wcstoq'; did you mean 'wcstol'? [-Wimplicit-function-declaration]
     retval=wcstoq(nptr,endptr,base);
            ^~~~~~
            wcstol

когда я использую gdb для отладки этого тестового примера, он переходит в правильную функцию, аналогичную описанной мной ситуации _GNU_SOURCE. Но функция работает неправильно, когда я не определил _GNU_SOURCE.

например:

Когда я проверяю регистр вне диапазона в x86_64, он должен установить retval= LLONG_MAX(0x7FFFFFFFFFFFFFFF), но на самом деле он установит retval= -1(0xFFFFFFFFFFFFFFFF). Результат также смутил меня, когда я тестировал его на других платформах ppc, он на самом деле установил retval=0x000000007FFFFFFF. когда я определил _GNU_SOURCE, функция работает нормально в x86_64 и ppc, она возвращает LLONG_MAX(0x7FFFFFFFFFFFFFFF).

мой вопрос:

1 Почему, когда я не определяю _GNU_SOURCE, но gcc все еще может найти правильную функцию?

2 Почему не удалось выполнить функцию, даже gcc нашел правильную, и в некоторых случаях эта функция все еще может использоваться, но в других случаях она идет не так, как надо *

3 Почему неудавшийся результат работы fuction отличается на разных платформах, как платформы архитектуры или другие факторы влияют на разные результаты?

4 Правильный способ использования функции расширения GNU?

Thks!

1 Ответ

0 голосов
/ 23 ноября 2018

Неявные объявления функций, расширение GCC, которое включено по умолчанию, используют тип возврата int, однако функция определена как возвращающая long long. При таком несоответствии типов может произойти все что угодно. На практике результаты зависят от соглашения о вызовах, и поэтому они различаются в зависимости от архитектуры.

Вы должны действительно скомпилировать с -Werror=implicit-function-declaration (или использовать C ++). Неявные объявления функций были удалены из C почти двадцать лет назад (в ИСО / МЭК 9899: 1999), но мы все еще не можем изменить значение по умолчанию GCC, потому что слишком много проверок autoconf прервется, что приведет к случайной потере программного обеспечения.

(я думаю, что вы хотели написать retval в своем вопросе вместо errno.)

...