通过引用和内联返回文字

时间:2013-03-24 11:45:14

标签: c++ inline pass-by-reference

据说,在C ++中通过引用返回文字是不好的,因为文字超出范围然后离开函数:

const char &ToBoolean(bool val) const 
{ 
    return val ? (const char &)"1" : (const char &)"0"; 
}

,但是在使用inline时,我猜这应该没问题,因为文字的范围现在在调用函数中,或者没有?例如:

inline const char &ToBoolean(bool val) const 
{ 
    return val ? (const char &)"1" : (const char &)"0"; 
}

这就是我计划使用它的方式:

void testToBoolean1()
{
     bool val = true;
     const char *valStr = ToBoolean(val);
     int result = strcmp("1", valStr);
     CPPUNIT_ASSERT_EQUAL(0, result);
}

更新

如果静态字符串没问题,那么这个怎么样?

inline const char *ToBoolean(bool val) const { 
    char boolStr[6];
    if (val) strcpy(boolStr, "true");
    else strcpy(boolStr, "false");
    return &boolStr;
}

使用VC ++ 2012编译并运行良好。

4 个答案:

答案 0 :(得分:5)

字符串文字与局部变量不同,它们在整个程序生命周期内保持活动状态。它们具有静态持续时间。您可以安全地将指针返回到字符串文字。

C ++ 11标准§2.14.5.8:

  

普通字符串文字和UTF-8字符串文字也称为窄字符串文字。窄字符串文字的类型为“n const char数组”,其中n是下面定义的字符串大小,并且具有静态存储持续时间(3.7)。

3.7.1静态存储时间
第1段:

  

......这些实体的存储应持续一段时间   程序(3.6.2,3.6.3)


为了清楚起见,字符串文字“1”的类型是char (*)[2]。这是因为,“1”的类型是char [2],并且指向2个字符的数组的指针被声明为char (*)[2],所以如果你需要获取它的地址。返回引用时,隐式c样式转换会转换为reinterpret_cast,基本上可以将任何类型的指针转​​换为任何其他类型,而不管其是否正确。你得到的是一个未定义的行为。如上所述,您可以安全返回的是指向字符串文字的指针。您需要将返回类型修改为:

char const* ToBoolean(bool val) const;

回答更新的问题:

您更新的解决方案只是将字符串文字复制到函数本地的数组中。该数组不存在于函数范围之外。所以不,不行。它似乎可行,但它会调用未定义的行为。 “true”和“false”本身具有静态持续时间,但您没有返回指向它们的指针,您正在将它们复制到本地数组并返回指向本地数组的指针。

答案 1 :(得分:4)

char const * char const& 不同(前者是指向char 的指针,后者是对a的引用单个 char 。字符串常量是静态分配的,因此可以安全地从函数返回指针。

inline char const* ToBoolean(bool val) const 
{ 
    return val ? "1" : "0"; 
}

答案 2 :(得分:2)

"1"是一个字符串文字,类型为“数组2 const char”。当您使用(const char &)"1"投射时,会产生reinterpret_cast<const char&>("1"),最终会给您带来未定义的行为。

也许你有意义:

inline const char &ToBoolean(bool val)
{ 
    return val ? '1' : '0'; 
}

注意单引号。这些是字符文字,而不是字符串文字。

但是,因为字符文字是prvalues,所以绑定到const char&会导致使用相应的值创建临时对象。然后将引用绑定到临时对象。但是,该临时对象将在完整表达式(return语句)结束时销毁,并且引用将保持悬空状态。

不,inline不会影响变量的范围或对象的生命周期。那将是愚蠢的,因为它只是提示编译器要做什么。这意味着编译器可以根据需要选择更改代码的含义。

因此,请尝试返回指向字符串文字的指针:

inline const char* ToBoolean(bool val)
{ 
    return val ? "1" : "0"; 
}

字符串文字具有静态存储持续时间,这意味着它们在程序的持续时间内存在。您可以返回指向字符串文字中第一个元素的指针,并确保它指向的对象始终有效。

答案 3 :(得分:1)

inline const char &ToBoolean(bool val) const 
{ 
    return val ? (const char &)"1" : (const char &)"0"; 
}

您为char返回一个字符串? - 另外,如果你真的必须返回const char *然后明确说明它。::

inline const char *ToBoolean(bool val) const 
{ 
    return val ? "1" : "0"; 
}