C++标准包含一个半着名的例子,在3.3.2中的"令人惊讶的"名称查找,"声明点":
int x = x;
Run Code Online (Sandbox Code Playgroud)
这初始化x自身,(原始类型)未初始化,因此具有不确定的值(假设它是一个自动变量).
这实际上是未定义的行为吗?
根据4.1"左值到右值转换",对未初始化的值执行左值到右值的转换是未定义的行为.右手是否x接受这种转换?如果是这样,示例实际上会有未定义的行为吗?
我以前认为在C99中,即使函数的副作用f和g干扰,虽然表达式f() + g()不包含序列点,f并且g会包含一些,所以行为将是未指定的:要么f()之前调用f()之前的g()或g().
我不再那么肯定了.如果编译器内联函数(即使未声明函数,编译器可能决定这样做inline)然后重新排序指令,该怎么办?可能有人得到上述两种不同的结果吗?换句话说,这是未定义的行为吗?
这不是因为我打算写这种东西,而是在静态分析器中为这样的语句选择最佳标签.
c c99 undefined-behavior sequence-points unspecified-behavior
首先,澄清一点,我不是在谈论解除引用无效指针!
考虑以下两个例子.
例1
typedef struct { int *p; } T;
T a = { malloc(sizeof(int) };
free(a.p); // a.p is now indeterminate?
T b = a; // Access through a non-character type?
Run Code Online (Sandbox Code Playgroud)
例2
void foo(int *p) {}
int *p = malloc(sizeof(int));
free(p); // p is now indeterminate?
foo(p); // Access through a non-character type?
Run Code Online (Sandbox Code Playgroud)
题
以上示例中的任何一个都会调用未定义的行为吗?
上下文
提出这个问题是为了回应这一讨论.建议是,例如,指针参数可以通过x86段寄存器传递给函数,这可能导致硬件异常.
根据C99标准,我们学习以下内容(强调我的):
[3.17] 不确定值 - 未指定的值或陷阱表示
然后:
[6.2.4 p2]当指向的对象到达其生命周期的末尾时,指针的值变得不确定.
然后:
[6.2.6.1 p5]某些对象表示不需要表示对象类型的值.如果对象的存储值具有这样的表示并且由不具有字符类型的左值表达式读取,则行为是未定义的.如果这样的表示是由副作用产生的,该副作用通过不具有字符类型的左值表达式修改对象的全部或任何部分,则行为是未定义的.这种表示称为 …
我一直在std::memcpy用来规避严格的混叠很长一段时间.
例如,检查a float,像这样:
float f = ...;
uint32_t i;
static_assert(sizeof(f)==sizeof(i));
std::memcpy(&i, &f, sizeof(i));
// use i to extract f's sign, exponent & significand
Run Code Online (Sandbox Code Playgroud)
但是,这次,我检查了标准,我还没有找到任何可以验证这一点的东西.我所发现的是这个:
对于平凡可复制类型T的任何对象(可能重叠的子对象除外),无论对象是否保持类型T的有效值,组成对象的基础字节([intro.memory])都可以复制到char,unsigned char或std :: byte([cstddef.syn])数组.40如果将该数组的内容复制回对象,则该对象应随后保持其原始值.[例如:
Run Code Online (Sandbox Code Playgroud)#define N sizeof(T) char buf[N]; T obj; // obj initialized to its original value std::memcpy(buf, &obj, N); // between these two calls to std?::?memcpy, obj might be modified std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar …
c++ strict-aliasing undefined-behavior language-lawyer c++17
围绕未定义行为(UB)的大多数对话都讨论了如何有一些平台可以做到这一点,或者一些编译器会这样做.
What if you are only interested in one platform and only one compiler (same version) and you know you will be using them for years?
Nothing is changing but the code, and the UB is not implementation-defined.
Once the UB has manifested for that architecture and that compiler and you have tested, can't you assume that from then on whatever the compiler did with the UB the first time, it will do that every time?
Note: I …
在C++中,有很多方法可以编写编译的代码,但会产生未定义的行为(维基百科).C#中有类似的东西吗?我们可以用编译的C#编写代码,但是有未定义的行为吗?
The question is pretty clear. The following gives the reason why I think these expressions might yield undefined behavior. I would like to know whether my reasoning is right or wrong and why.
Short read:
(IEEE 754) double is not Cpp17LessThanComparable since < is not a strict weak ordering relation due to NaN. Therefore, the Requires elements of std::min<double> and std::max<double> are violated.
Long read:
All references follow n4800. Specifications of std::min and std::max are given …
c++ floating-point undefined-behavior c++-standard-library language-lawyer
我们有一个烦人的错误,我无法解释这段代码:
unsigned char bitmap[K_BITMAP_SIZE] = {0} ;
SetBit(bitmap, K_18); // Sets the bit #18 to 1
for(size_t i = 0; i < K_END; ++i)
{
if(TestBit(bitmap, i)) // true for 18
{
size_t i2 = getData(i); // for 18, will return 15
SetBit(bitmap, i2); // BUG: IS SUPPOSED TO set the bit #15 to 1
}
}
Run Code Online (Sandbox Code Playgroud)
__forceinline使用getData函数时才会在Visual C++ 2008上发生(默认情况下,VC++ 2008不会内联该函数,而VC++ 2010会这样做)奖金信息:
1- BenJ评论说这个问题没有出现在Visual C++ 2012上,这意味着这可能是编译器中的一个错误
2-如果我们 …
c++ visual-studio-2010 compiler-optimization undefined-behavior visual-studio
考虑
#include <iostream>
int main()
{
double a = 1.0 / 0;
double b = -1.0 / 0;
double c = 0.0 / 0;
std::cout << a << b << c; // to stop compilers from optimising out the code.
}
Run Code Online (Sandbox Code Playgroud)
我一直认为这a将是+ Inf,b将是-Inf,并且c将是NaN.但我也听到传言说严格来说浮点除零的行为是未定义的,因此上面的代码不能被认为是可移植的C++.(理论上,这会消除我的百万行加上代码堆栈的完整性.糟糕.)
谁是对的?
注意我对实现定义感到满意,但我在谈论吃猫,在这里恶魔打喷嚏的未定义行为.
c++ floating-point divide-by-zero undefined-behavior language-lawyer
我对以下代码感到有点困惑:
#include <iostream>
const char* f()
{
const char* arr[]={"test"};
return arr[0];
}
int main()
{
auto x = f();
std::cout << x;
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这段代码应该是UB(未定义的行为).我们返回一个指向本地范围内的C风格数组元素的指针.事情应该出问题.但是,我测试过的编译器都没有抱怨(我用过-Wall -Wextra -pedanticg ++和clang).valgrind也不抱怨.
上面的代码是有效的还是人们会想到的UB?
PS:运行它似乎产生"正确"的结果,即显示"测试",但这并不表示正确性.