简体   繁体   English

使用没有显式强制转换的常量调用未定义行为?

[英]is using a constant without an explicit cast invoke undefined behavior?

Upon invoking a function,or returning a value from a function,that expects a value of type T ,does using a constant literal without explicit cast invoke undefined behavior? 在调用一个函数或从一个函数返回一个期望值为T类型的值的值时,是否使用不带显式强制转换的常量文字调用未定义的行为?

For example,we have a function who's prototype is long foo(unsigned long x); 例如,我们有一个函数的原型是long foo(unsigned long x); Invocation: foo(4); //does this invoke UB? 调用: foo(4); //does this invoke UB? foo(4); //does this invoke UB?

long foo(unsigned long x) { x += 10; return 10; } // does this invoke UB ?

should we write foo((unsigned long)4) and return (long)10 ?? 我们应该写foo((unsigned long)4)return (long)10吗?

No, it is all well-defined. 不,这都是定义明确的。

There exists an implicit conversion rule between the two types, so the int is simply converted to an unsigned long and the program works as expected. 两种类型之间存在一个隐式转换规则,因此int会简单地转换为unsigned long ,并且程序会按预期运行。

Type of literal 4 is int . 文字4类型为int (In C section 6.4.4.1 Integer constants, similar section available in C++ also) (在C节6.4.4.1整数常量中,类似的节在C ++中也可用)

Implicit conversion from int to unsigned long is well defined in both C and C++. 在C和C ++中都很好地定义了从intunsigned long隐式转换。 (In C section 6.3.3.1) (在C第6.3.3.1节中)

should we write foo((unsigned long)4) and return (long)10? 我们应该写foo((unsigned long)4)并返回(long)10吗?

Both of your example are well defined, so this conversion though acceptable is superfluous. 您的两个示例均定义良好,因此尽管可以接受这种转换是多余的。

Consider this C code: 考虑下面的C代码:

// foo.c
int foo(unsigned long x) { }

and

// main.c
int foo();

int main()
{
     foo(4);    // UB
     foo((unsigned long)4);   // OK
}

The foo(4) call is UB because when you are calling a function with no prototype in scope, you must manually make sure the parameters match. foo(4)调用是UB,因为在调用范围内没有原型的函数时,必须手动确保参数匹配。 The default argument promotions occur but that's all. 默认参数提升出现,仅此而已。

Of course, writing the cast is a bad solution from the point of view of writing robust code. 当然,从编写健壮的代码的角度来看,编写强制转换是一个不好的解决方案。 The better solution would be to write a prototype: 更好的解决方案是编写一个原型:

int foo(unsigned long);

in a header file which is included from both the .c files. 包含在两个.c文件中的头文件中。


The return 10; return 10; case can never be UB because the function's true return type is known to the compiler when it is compiling the code inside the function body. case永远不能是UB,因为编译器在编译函数体内的代码时会知道函数的真实返回类型。

No, it wouldn't make sense, since such argument is passed by value in both C and C++: 不,这没有意义,因为这样的参数在C和C ++中都是通过值传递

long foo(unsigned long x);

You may think of it technicaly as x parameter is a local automatic variable defined inside foo and assigned with the value of passed argument: 您可能认为它是技术上的,因为x参数是在foo内部定义的本地自动变量,并分配有传递参数的值:

unsigned long x = 4;

If type of argument does not match with parameter, then compiler tries with implicit conversion. 如果参数的类型与参数不匹配,则编译器将尝试进行隐式转换。 For instance, an argument of type double is silenty converted into of type unsigned long , even it means loss of information (you might get a compiler warning though). 例如,将double类型的参数静默转换为unsigned long类型,即使这意味着信息丢失(尽管您可能会收到编译器警告)。

You may however get into trouble, when you mark type of x parameter as reference (C++ only): 但是,当您将x参数的类型标记为引用时,可能会遇到麻烦(仅C ++):

long foo(unsigned long& x);

Here, the compiler would not allow you to call it as foo(4) , because you are now passing by reference, and 4 cannot be modified as such. 在这里,编译器不允许您将其称为foo(4) ,因为您现在通过引用传递,并且不能这样修改4 You may however pass it if the parameter is marked with const qualifier: 但是,如果参数用const限定符标记,则可以传递它:

long foo(const unsigned long& x);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用reinterpret_cast是否会引起未定义的行为? - Does this use of reinterpret_cast invoke an undefined behavior? 是否取消引用const_cast的指针ALWAYS会调用未定义的行为? - Does dereferencing a pointer from a const_cast ALWAYS invoke undefined behavior? 在布尔值上使用按位非运算符(〜)是否会调用未定义的行为? - Does using bitwise not operator (~) on boolean values invoke Undefined Behavior? 使用联合的这种类型别名会调用未定义的行为吗? - Does this type aliasing using union invoke undefined behavior? 使用const_cast &lt;&gt;时未定义的行为在哪里? - Where is the undefined behavior when using const_cast<>? 在内存映射中使用reinterpret_cast时处理未定义的行为 - Dealing with undefined behavior when using reinterpret_cast in a memory mapping 在枚举类上使用`reinterpret_cast`-有效或未定义的行为? - Using `reinterpret_cast` on an enum class - valid or undefined behavior? 是否使用对通过 reinterpret_cast 未定义行为进行转换的指针的引用? - Is using reference to pointer that was casted with reinterpret_cast undefined behavior? 这是const_cast未定义的行为吗? - Is this const_cast undefined behavior? 错误的演员表 - 是演员表或使用未定义的行为 - Incorrect cast - is it the cast or the use which is undefined behavior
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM