开发者

Self-Promoting Data Types

开发者 https://www.devze.com 2023-02-04 19:24 出处:网络
I read through the method for using variadic functions in C at http://www.gnu.org/s/libc/manual/html_node/Argument-Macros.html#Argument-Macros

I read through the method for using variadic functions in C at http://www.gnu.org/s/libc/manual/html_node/Argument-Macros.html#Argument-Macros

However, I was unable to grasp the meaning of self-promoting data types. What are开发者_如何学C they & how are they different from non-self-promoting data types?


Here is the C99 standard; "self-promoting" types are those which promote to themselves when the default argument promotions (§6.5.2.2 paragraph 6, referencing the integer promotions described in §6.3.1.1) are applied.

My reading of the va_arg definition (§7.15.1.1) is that this limitation is implied by the standard. The relevant part is in paragraph 2:

[...] or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions) [...]

which is quite clear about the type of the actual next argument being promoted, but I read as not saying anything about type being promoted. (I think the "(as promoted...)" clause is just a reminder that default argument promotions are performed on the trailing arguments when a varargs function is called.)

This item in the list of undefined behaviour in §J.2 supports this reading:

— The va_arg macro is invoked when there is no actual next argument, or with a specified type that is not compatible with the promoted type of the actual next argument, with certain exceptions (7.15.1.1).

(although yes, I know, Annex J is "informative" rather than "normative"...).

In which case: va_arg(ap, float) (for example) cannot be valid - type in that case is float, but the promoted type of the actual next argument cannot possibly be float (a float argument would be promoted to double).


This seems to be a glibc restriction, the C standard doesn't have that.

The idea behind this is that integer types that have so-called "conversion rank" smaller than int are automatically promoted to signed or unsigned int. A va_arg function then finds such a wider argument. The va_arg macro must then first read the wider argument of type int, say, and then cast it back to the original type.

(Same holds for float w.r.t to double.)

For the unaware programmer this can have surprising result, so I agree with the idea that this should be avoided. The description you are citing seems to imply that it is imposed to not use a small type. This is bogus and as I said not in alignment with the standard. On the other hand if you write code as they suggest you will never have a portability issue with that because this is a restriction and not an extension.

0

精彩评论

暂无评论...
验证码 换一张
取 消