首页 > TAG信息列表 > undefined-behavior
c-为什么这种不确定的行为?
这是示例代码: X * makeX(int index) { return new X(index); } struct Tmp { mutable int count; Tmp() : count(0) {} const X ** getX() const { static const X* x[] = { makeX(count++), makeX(count++) }; return x; } }; 这将报告静态数被未定义的C移位运算符行为和包装“模式空间”所迷惑
我对在article on undefined C++ behavior的Shift Operators部分中阅读的内容感到困惑. On the ARM architecture, the shift operators always behave as if they take place in a 256-bit pattern space, regardless of the operand size–that is, the pattern repeats, or “是否在C 14中始终定义了对可复制对象的复制?
对于trivially copyable型T,请考虑: void f(T z) { T a; T b; std::memcpy(&b, &a, sizeof(T)); a = z; b = z; // ... } 是否在C 14中定义了此片段的行为,如果 > T是char, > T是int,或> T是struct {int数据; }; ? 假设f传递了一个持有有效值的对象. 如果将memcc-当用非虚拟析构函数“删除”基类时,Clang和GCC会做什么?
已经有a question询问删除缺少虚拟析构函数的基类的指针的“现实世界”行为,但问题仅限于非常有限的情况(派生类没有具有非平凡析构函数的成员) ,并且可接受的答案只是说,如果不检查每个编译器的行为,就无法知道. ….但这实际上不是很有帮助;知道每个编译器的行为可能都不同,这并不c-限制由不确定行为引起的混乱?
从我的阅读中可以了解到,undefined-behavior是在编译时给编译器留下几种不同的选择的结果.但是,这并不意味着如果要遵循严格的编码实践(例如将每个赋值和每个等式放在单独的语句中,进行适当的调试和注释),那么在查找未定义的来源时就不会造成重大问题-行为. 此外,对于每个出现的错c-自动检查std :: vector中的界限
这个问题已经在这里有了答案: > Compile time triggered range check for std::vector 2个 在积极开发使用std :: vector的类的过程中,经常会发生索引超出如何根据c标准访问对象表示?
如何访问object representation?为了回答这个问题,我将其分为两个问题: 1.如何获取对象表示的指针? 根据标准,我看不到任何获取对象表示形式的指针的方法.通常建议以这种方式获取它: some_type obj{}; const char * rep = reinterpret_cast<const unsigned char*>(&obj); 然而,在标准c-通过引用抛出非常量临时对象
通过非常量引用将构造在堆栈上的对象扔到try块中,捕获它并对其进行修改,然后通过引用另一个catch块将它抛出,是否有任何问题? 以下是我所指的简短示例. struct EC { EC(string msg) { what = msg; } string where; string what; void app(string& t) { where += tc – gcc 4.4上的“纯虚函数”,但不适用于较新版本或clang 3.4
我有一个MCVE,在我的一些机器崩溃时使用g版本4.4.7进行编译但是与clang版本3.4.2和g版本6.3一起使用. 我想要一些帮助来知道它是来自未定义的行为还是来自这个古老版本的gcc的实际错误. 码 #include <cstdlib> class BaseType { public: BaseType() : _present( false ) {}c – 如何实现没有未定义行为的快速逆sqrt?
参见英文答案 > What’s a proper way of type-punning a float to an int and vice-versa? 7个 根据我对strict aliasing rule的理解,fast inverse square root的此代码将导致C中的未定义行为: float Q_rc – 临时对象最初是const吗?
这个代码是UB吗? struct A { void nonconst() {} }; const A& a = A{}; const_cast<A&>(a).nonconst(); 换句话说,(临时)对象最初是const吗?我已经查看了标准,但找不到答案,所以会对相关部分的引用表示赞赏. 编辑:对于那些说A {}不是const的人,你可以做A {}.nonconst()吗?解决方法:c – 不正确的强制转换 – 是未定义行为的强制转换或使用
如果我从Base转换为Derived类型,但Base类型不是派生类型的实例,但只使用结果,是否会得到未定义的行为? 很难理解我在问什么?看看这个例子: struct Animal { int GetType(){...} }; struct Dog : Animal { bool HasLoudBark(){...}}; struct Cat : Animal { bool HasEvilStare(){...}c / c中未定义的行为:i i vs i i [复制]
参见英文答案 > Why are these constructs using pre and post-increment undefined behavior? 14个 想象一下,我们有以下代码: int i = 1; int j = i++ + ++i; 我知道这是一个未定义的行为,因为在分号之C标准中未定义行为段落中的[注意]是什么意思?
如user Tony points out所述,C标准第1.3.12段中有[注] permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the envirc – 使用GCC未定义行为消毒剂
今天我读了关于GCC Undefined Behavior Sanitizer(ubsan)的an article.但是,当我按照那里的步骤(将-fsanitize = undefined添加到我的代码中)时,编译器(UCCntu 15.04上的GCC 4.9.2)表示某些引用未定义: ||=== Build: Debug in Entangle (compiler: GNU GCC Compiler) ===| obj/Debuc – 在bool中设置额外位会使其同时为true和false
如果我得到一个bool变量并将其第二位设置为1,则变量同时计算为true和false.使用带-g选项的gcc6.3编译以下代码(gcc-v6.3.0 / Linux / RHEL6.0-2016-x86_64 / bin / g -g main.cpp -o mytest_d)并运行可执行文件.你得到以下. T如何同时等于真和假? value bits ----c – 直接调用析构函数后是`new(this)MyClass();`未定义的行为?
在this question of mine,@ DeadMG说通过this指针重新初始化类是未定义的行为.标准中有没有提到它? 例: #include <iostream> class X{ int _i; public: X() : _i(0) { std::cout << "X()\n"; } X(int i) : _i(i) { std::cout << "X(int)\n"; } ~X(){为什么不删除在C 11中具有带有副作用未定义行为的析构函数的对象?
This answer报价C 11标准3.8: if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the dec – 取消引用悬空指针是不确定的行为?
我无法在标准中找到该程序未定义的位置: #include <iostream> int main() { int *p; { int n = 45; p = &n; } std::cout << *p; } §3.8对象生命周期中的所有情况似乎都不适用于此处.解决方法:我不是100%肯定因为措辞,但看起来这是由3.8 / 6覆c – 指针变量只是与某些运算符整数还是“符号”?
编辑:原始的单词选择令人困惑.术语“象征性”比原始术语(“神秘”)要好得多. 在关于我之前的C问题的讨论中,我被告知指针是 >“a simple value type much like an integer” >不是“mystical”>“The Bit pattern (object representation) contains the value (value representation访问超出C和C限制的数组
int data[8]; data[9] = 1; c标准对此有何评论?这是未定义的行为吗? 至少C编译器(gcc -std = c99 -pedantic -W -Wall)对此没有任何说明. 谢谢.解决方法:访问数组边界外部是未定义的行为,来自c99 draft standard部分附件J.2 J.2未定义的行为包括以下几点: An array subscript is oc – 如果计数大于类型的宽度,是右移未定义的行为吗?
我刚检查了C标准.看来以下代码不应该是undefined behavior: unsigned int val = 0x0FFFFFFF; unsigned int res = val >> 34; // res should be 0 by C++ standard, // but GCC gives warning and res is 67108863 并从标准: The value of E1 >>c – 在调用toupper(),tolower()等之前,是否需要转换为unsigned char?
不久之前,StackOverflow上有名望的人在评论中写道,在调用std :: toupper(和类似函数)之前,有必要将char-argument转换为unsigned char. 另一方面,Bjarne Stroustrup没有提到在C编程语言中这样做的必要性. 他只是喜欢使用toupper string name = "Niels Stroustrup"; void m3() {c – 什么时候类型惩罚指针在实践中是安全的?
我的一位同事正在研究与二进制数据阵列一起使用的C代码.在某些地方,他的代码就像 char *bytes = ... T *p = (T*) bytes; T v = p[i]; // UB 这里,T有时可以是short或int(分别假设为16和32位). 现在,与我的同事不同,我属于“没有UB,如果可能的话”阵营,而他更像是“如果有效,那就c – 为什么删除void *是UB而不是编译错误?
为什么通过void *删除对象是未定义的行为,而不是编译错误? void foo(void* p) { delete p; } 这段代码编译并生成代码,虽然gcc和clang上有警告(令人惊讶的是,ICC没有发出警告): :2:5: warning: cannot delete expression with pointer-to-‘void’ type ‘void *’ [-Wdel