通过引用和内联返回文本 假定C++中引用的文字是坏的,因为文字超出范围,然后留下函数: const char &ToBoolean(bool val) const { return val ? (const char &)"1" : (const char &)"0"; }
,但是当使用通过引用和内联返回文本 假定C++中引用的文字是坏的,因为文字超出范围,然后留下函数: const char &ToBoolean(bool val) const { return val ? (const char &)"1" : (const char &)"0"; },c++,inline,pass-by-reference,C++,Inline,Pass By Reference,,但是当使用inline时,我猜这应该是可以的,因为文本的作用域现在在调用函数中,或者不是?例如: inline const char &ToBoolean(bool val) const { return val ? (const char &)"1" : (const char &)"0"; } 以下是我计划如何使用它: void testToBoolean1() { bool val = true; const char *val
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进行编译并运行良好。字符串文字与局部变量不同,它们在整个程序生命周期内保持活动状态。它们具有静态持续时间生命周期。您可以安全地将指针返回到字符串文字 C++11标准§2.14.5.8: 普通字符串文字和UTF-8字符串文字也称为窄字符串文字。窄字符串文字的类型为“array of 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样式转换将转移到一个重新解释转换
,它本质上可以将任何类型的指针转换为任何其他类型,而不管正确性如何。在你的情况下,它带给你的是一种未定义的行为。如上所述,您可以安全地返回一个指向字符串文本的指针。您需要将退货类型修改为:
char const* ToBoolean(bool val) const;
对更新问题的回答: 更新后的解决方案仅将字符串文本复制到函数的本地数组中。数组不存在于函数范围之外。所以不,这不好。它似乎可以工作,但它调用了未定义的行为。“true”和“false”本身具有静态持续时间生存期,但您没有返回指向它们的指针,而是将它们复制到本地数组并返回指向本地数组的指针。char const*与char const&(前者是指向字符的指针,后者是对单个字符的引用。字符串常量是静态分配的,因此从函数返回指向它们的指针是安全的
inline char const* ToBoolean(bool val) const
{
return val ? "1" : "0";
}
您为char
返回一个字符串-另外,如果确实必须返回const char*
,则显式声明它:
inline const char *ToBoolean(bool val) const
{
return val ? "1" : "0";
}
“1”
是一个类型为“array of 2const
char
”的字符串文字。当您使用(const char&)“1”
对其进行强制转换时,这会导致重新解释强制转换(“1”)
,最终导致未定义的行为
也许你的意思是:
inline const char &ToBoolean(bool val)
{
return val ? '1' : '0';
}
注意单引号,它们是字符文字,而不是字符串文字
但是,由于字符文字是prvalues,因此绑定到常量char&
会产生一个具有相应值的临时对象。然后将引用绑定到该临时对象。但是,该临时对象将在完整表达式结束时销毁(return
语句)引用将悬空
不,inline
不会影响变量的范围或对象的生存期。这很愚蠢,因为这只是给编译器的一个提示,告诉他们该做什么。这意味着编译器可以选择更改代码的含义,如果它想这样做的话
因此,请尝试返回指向字符串文字的指针:
inline const char* ToBoolean(bool val)
{
return val ? "1" : "0";
}
字符串文字具有静态存储持续时间,这意味着它们在程序的持续时间内存在。您可以返回指向字符串文字中第一个元素的指针,并确保它指向的对象始终有效。
inline
与字符串文字或作用域无关…inline
也有little与编译器实际内联的函数有关。@jrok我现在知道正确的问题应该是“内联是否扩展了函数变量范围”。如果方法是const char&ToFloat(float val)
并返回了对函数localchar floatStr[100]的引用
,那么内联
和不使用内联
之间还会有区别吗?@IngeHenriksen不会编译。不能将数组作为常量字符返回&
@IngeHenriksen有两个问题:1)使用C样式转换使情况变得更糟。(const\u UTF8*)&boolStr
将是一个重新解释
的演员。虽然在这个特殊的例子中,你可能会侥幸逃脱(我还没有完全确认)2)在函数结束时,boolStr
数组将被销毁。如果返回指向它的指针,指针将悬空。@IngeHenrikseninline
不会影响变量的范围或对象的生存期。你甚至不应该把它看作是移动函数代码,因为标准没有这么说。该标准只是对内联
函数设置了某些限制,这意味着编译器可以在需要时移动代码。但是,inline
不会影响程序的语义。@IngeHenriksen:inline
只告诉编译器。1.如果可能,尝试用函数体替换函数调用&2。Relax规则w.r.t一个定义规则(ODR)<代码>#1可能是也可能不是,始终执行#2
<代码>内联仅此而已。我认为您希望删除强制转换。@IngeHenriksen不认为这意味着您的代码没有问题。绝对不是。您没有返回指向字符串文本的指针。你把它投给了一个
inline const char* ToBoolean(bool val)
{
return val ? "1" : "0";
}