Does this invoke undefined behaviour?

萝らか妹 提交于 2019-12-17 16:50:45

问题


Consider the following C program:

#include <stdio.h>

int main(){
    int a =-1;
    unsigned b=-1;
    if(a==b)
        printf("%d %d",a,b);
    else
       printf("Unequal");
    return 0;
 }

In the line printf("%d %d",a,b);, "%d" is used to print an unsigned type. Does this invoke undefined behavior and why?


回答1:


Although you are explicitly allowed to use the va_arg macro from <stdarg.h> to retrieve a parameter that was passed as an unsigned as an int (7.15.1.1/2), in the documentation for fprintf (7.19.6.1/9) which also applies to printf, it explicitly states that if any argument is not the correct type for the format specifier - for an unmodified %d, that is int - then the behaviour is not defined.

As @bdonlan notes in a comment, if the value of b (in this case 2^N - 1 for some N) is not representable in an int then it would be undefined behavior to attempt to access the value as an int using va_arg in any case. This would only work on platforms where the representation of an unsigned used at least one padding bit where the corresponding int representation had a sign bit.

Even in the case where the value of (unsigned)-1 can be represented in an int, I still read this as being technically undefined behavior. As part of the implementation, it would seem to be allowed for an implementation to use built in magic instead of va_args to access the parameters to printf and if you pass something as an unsigned where an int is required then you have technically violated the contract for printf.




回答2:


The standard isn't 100% clear on this point. On one hand, you get the specification for va_arg, which says (§7.15.1.1/2):

If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases:

  • one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;
  • one type is pointer to void and the other is a pointer to a character type.

On the other hand, you get the specification of printf (§7.19.6.1/9):

If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined."

Given that it's pretty much a given that printf will retrieve arguments with va_arg, I'd say you're pretty safe with values that can be represented in the target type, but not otherwise. Since you've converted -1 to an unsigned before you pass it, the value will be out of the range that can be represented in a signed int, so the behavior will be undefined.




回答3:


Yes, the if will always evaluate to true and the printf will attempt to print an unsigned as a signed. Since the signed type may have trap representations, this may be UB if the sign representation is one's complement.



来源:https://stackoverflow.com/questions/5851524/does-this-invoke-undefined-behaviour

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!