Саморекламируемые типы данных - PullRequest
5 голосов
/ 12 января 2011

Я прочитал метод использования переменных функций в C на http://www.gnu.org/s/libc/manual/html_node/Argument-Macros.html#Argument-Macros

Однако я не смог понять значение саморекламируемых типов данных. Чем они отличаются и чем они отличаются от несамостоятельных типов данных?

Ответы [ 2 ]

4 голосов
/ 13 января 2011

Вот стандарт C99 ;«саморекламируемые» типы - это те, которые рекламируют себя, когда применяются стандартные аргументы продвижения (§6.5.2.2 параграф 6, ссылаясь на целочисленные продвижения, описанные в §6.3.1.1).

Мое прочтение определения va_arg (§7.15.1.1) заключается в том, что это ограничение подразумевается стандартом .Соответствующая часть находится в абзаце 2:

[...] или если type не совместим с типом фактического следующего аргумента (как продвигается в соответствии с аргументом по умолчанию)продвижение) [...]

, что совершенно ясно о типе фактического следующего аргумента, который продвигается, но я читаю как ничего не говорящего о продвигаемом типе .(Я думаю, что предложение «(как повышено ...)» является лишь напоминанием о том, что продвижение аргументов по умолчанию выполняется на конечных аргументах при вызове функции varargs.)

Этот элемент в списке неопределенного поведенияв §J.2 поддерживается это чтение:

- Макрос va_arg вызывается, когда нет фактического следующего аргумента, или с указанным типом, который не совместим с повышенным типом фактическогоследующий аргумент, за некоторыми исключениями (7.15.1.1).

(хотя да, я знаю, Приложение J является "информативным", а не "нормативным" ...).

В этом случае: va_arg(ap, float) (например) не можетбыть действительным - type в этом случае - float, но тип фактического следующего аргумента может быть не более float (аргумент float будет повышен до double).

2 голосов
/ 12 января 2011

Кажется, что это ограничение glibc, стандарт C не имеет этого.

Идея, лежащая в основе этого, состоит в том, что целочисленные типы, имеющие так называемый «рейтинг преобразования», меньший, чем int, автоматическиповышен до signed или unsigned int.Затем функция va_arg находит такой более широкий аргумент.Макрос va_arg должен сначала прочитать более широкий аргумент, скажем, типа int, а затем привести его к исходному типу.

(То же самое относится к float по отношению к double.)

Для неопытного программиста это может привести к неожиданным результатам, поэтому я согласен с идеей, что этого следует избегать.Описание, которое вы цитируете, по-видимому, подразумевает, что оно навязано, чтобы не использовать маленький тип.Это подделка и, как я уже сказал, не в соответствии со стандартом.С другой стороны, если вы пишете код так, как он предлагает, у вас никогда не будет проблем с переносимостью, потому что это ограничение, а не расширение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...