繁体   English   中英

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

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

在调用一个函数或从一个函数返回一个期望值为T类型的值的值时,是否使用不带显式强制转换的常量文字调用未定义的行为?

例如,我们有一个函数的原型是long foo(unsigned long x); 调用: 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 ?

我们应该写foo((unsigned long)4)return (long)10吗?

不,这都是定义明确的。

两种类型之间存在一个隐式转换规则,因此int会简单地转换为unsigned long ,并且程序会按预期运行。

文字4类型为int (在C节6.4.4.1整数常量中,类似的节在C ++中也可用)

在C和C ++中都很好地定义了从intunsigned long隐式转换。 (在C第6.3.3.1节中)

我们应该写foo((unsigned long)4)并返回(long)10吗?

您的两个示例均定义良好,因此尽管可以接受这种转换是多余的。

考虑下面的C代码:

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

// main.c
int foo();

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

foo(4)调用是UB,因为在调用范围内没有原型的函数时,必须手动确保参数匹配。 默认参数提升出现,仅此而已。

当然,从编写健壮的代码的角度来看,编写强制转换是一个不好的解决方案。 更好的解决方案是编写一个原型:

int foo(unsigned long);

包含在两个.c文件中的头文件中。


return 10; case永远不能是UB,因为编译器在编译函数体内的代码时会知道函数的真实返回类型。

不,这没有意义,因为这样的参数在C和C ++中都是通过值传递

long foo(unsigned long x);

您可能认为它是技术上的,因为x参数是在foo内部定义的本地自动变量,并分配有传递参数的值:

unsigned long x = 4;

如果参数的类型与参数不匹配,则编译器将尝试进行隐式转换。 例如,将double类型的参数静默转换为unsigned long类型,即使这意味着信息丢失(尽管您可能会收到编译器警告)。

但是,当您将x参数的类型标记为引用时,可能会遇到麻烦(仅C ++):

long foo(unsigned long& x);

在这里,编译器不允许您将其称为foo(4) ,因为您现在通过引用传递,并且不能这样修改4 但是,如果参数用const限定符标记,则可以传递它:

long foo(const unsigned long& x);

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM