3

Supposedly, returning a literal by reference in C++ is bad since the literal goes out of scope then leaving the function:

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

, but when using inline I'm guessing this should be ok since the literal's scope is now in the calling function, or no? Example:

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

This is how I plan to use it:

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

Update.

If static strings are ok, then how about this?

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

This compiles and runs fine using VC++ 2012.

4

4 回答 4

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 样式转换会演变为 a reinterpret_cast,它基本上可以将任何类型的指针转​​换为任何其他类型,而与正确性无关。在您的情况下,它带给您的是未定义的行为。如上所述,您可以安全地返回一个指向字符串文字的指针。您需要将返回类型修改为:

char const* ToBoolean(bool val) const;

回答更新的问题:

您更新的解决方案只是将字符串文字复制到函数本地的数组中。该数组不存在超出函数范围。所以不,这不好。它可能看起来有效,但它会调用未定义的行为。“true”和“false”本身具有静态持续时间生命周期,但您没有返回指向它们的指针,而是将它们复制到本地数组并返回指向本地数组的指针。

于 2013-03-24T11:52:26.803 回答
4

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

inline char const* ToBoolean(bool val) const 
{ 
    return val ? "1" : "0"; 
}
于 2013-03-24T11:53:06.527 回答
2

"1"是类型为“array of 2 const char”的字符串文字。当您使用 进行转换时(const char &)"1",这会导致reinterpret_cast<const char&>("1")最终给您未定义的行为。

也许你的意思是:

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

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

但是,由于字符文字是纯右值,因此绑定到const char&结果会导致使用相应值生成临时对象。然后引用绑定到临时对象。但是,该临时对象将在完整表达式(语句)的末尾被销毁,return并且引用将悬空。

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

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

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

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

于 2013-03-24T11:58:59.543 回答
1
inline const char &ToBoolean(bool val) const 
{ 
    return val ? (const char &)"1" : (const char &)"0"; 
}

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

inline const char *ToBoolean(bool val) const 
{ 
    return val ? "1" : "0"; 
}
于 2013-03-24T11:53:59.610 回答