在没有显式转换的情况下使用常量调用未定义的行为?

时间:2016-05-05 11:47:24

标签: c++ c function undefined-behavior

在调用函数或从函数返回值时,需要类型为T的值,是否使用常量文字而没有显式转换调用未定义的行为?

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

4 个答案:

答案 0 :(得分:6)

不,这一切都很明确。

两种类型之间存在隐式转换规则,因此int只是转换为unsigned long,程序按预期工作。

答案 1 :(得分:3)

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

intunsigned long的隐式转换在C和C ++中都有明确的定义。 (在C部分6.3.3.1中)

  

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

您的两个示例都已明确定义,因此这种转换虽然可以接受但是多余的。

答案 2 :(得分:0)

考虑这个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;情况永远不能是UB,因为编译器在编译函数体内的代码时,函数的真实返回类型是已知的。

答案 3 :(得分:0)

不,这没有意义,因为这样的参数在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);