相关疑难解决方法(0)

C++标准是否允许未初始化的bool使程序崩溃?

我知道C++ 中的"未定义行为"几乎可以让编译器做任何想做的事情.但是,我遇到了让我感到惊讶的崩溃,因为我认为代码足够安全.

在这种情况下,真正的问题仅发生在使用特定编译器的特定平台上,并且仅在启用了优化时才发生.

我尝试了几件事来重现问题并将其简化到最大程度.这是一个名为的函数的摘录Serialize,它将获取bool参数,并将字符串true或复制false到现有的目标缓冲区.

如果bool参数是未初始化的值,那么这个函数是否会在代码审查中,没有办法告诉它实际上可能会崩溃?

// Zero-filled global buffer of 16 characters
char destBuffer[16];

void Serialize(bool boolValue) {
    // Determine which string to print based on boolValue
    const char* whichString = boolValue ? "true" : "false";

    // Compute the length of the string we selected
    const size_t len = strlen(whichString);

    // Copy string into destination buffer, which is zero-filled (thus already null-terminated)
    memcpy(destBuffer, whichString, len);
}
Run Code Online (Sandbox Code Playgroud)

如果使用clang 5.0.0 +优化执行此代码,它将/可能崩溃.

boolValue ? "true" …

c++ abi llvm undefined-behavior llvm-codegen

482
推荐指数
5
解决办法
3万
查看次数

在这种情况下,为什么bool而不是bool都返回true?

这是我的代码:

#include <cstring>
#include <iostream>
int main() {
    bool a;
    memset(&a, 0x03, sizeof(bool));
    if (a) {
        std::cout << "a is true!" << std::endl;
    }
    if (!a) {
        std::cout << "!a is true!" << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

它输出:

a is true!
!a is true!
Run Code Online (Sandbox Code Playgroud)

似乎!运算符bool仅反转最后一位,但每个不相等的值0都被视为true.这导致显示的行为,这在逻辑上是错误的.这是实施中的错误,还是规范允许这样做?请注意,memset可以省略,并且行为可能是相同的,因为a包含内存垃圾.

我正在使用gcc 4.4.5,其他编译器可能会采用不同的方式.

c++ boolean

69
推荐指数
2
解决办法
4813
查看次数

陷阱表示

  1. 什么是C中的陷阱表示(某些示例可能有帮助)?这适用于C++吗?

    float f=3.5;
    int *pi = (int*)&f;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 编辑:我知道'pi'违反了别名规则,根据C标准它是UB.至少在海湾合作委员会它没有产生任何错误,但警告.在这个实现(即GCC)中,假设sizeof(int) == sizeof(float)do f*pi具有相同的二进制表示/模式?MSVC怎么样?

c c++ gcc visual-studio-2010

63
推荐指数
3
解决办法
1万
查看次数

在布尔中设置额外的位可使其同时为真和为假

如果我得到一个bool变量并将其第二位设置为1,则变量同时评估为true和false。使用带有-g选项(gcc-v6.3.0/Linux/RHEL6.0-2016-x86_64/bin/g++ -g main.cpp -o mytest_d)的gcc6.3编译以下代码,然后运行可执行文件。您得到以下内容。

T如何同时等于真和假?

       value   bits 
       -----   ---- 
    T:   1     0001
after bit change
    T:   3     0011
T is true
T is false
Run Code Online (Sandbox Code Playgroud)

当您使用不同的语言(例如fortran)调用函数时,可能会发生这种情况,其中对和错的定义与C ++不同。对于fortran,如果任何位都不为0,则该值为true;如果所有位为零,则该值为false。

#include <iostream>
#include <bitset>

using namespace std;

void set_bits_to_1(void* val){
  char *x = static_cast<char *>(val);

  for (int i = 0; i<2; i++ ){
    *x |= (1UL << i);
  }
}

int main(int argc,char *argv[])
{

  bool T = 3;

  cout <<"       value   bits " <<endl;
  cout <<" …
Run Code Online (Sandbox Code Playgroud)

c++ evaluation boolean abi undefined-behavior

40
推荐指数
2
解决办法
4718
查看次数

为什么c ++中的char和bool大小相同?

我正在阅读C++编程语言.Stroustrup在其中陈述sizeof(char) == 11 <= sizeof(bool).具体取决于实施.为什么像布尔这样的简单值与char相同?

c++ boolean

31
推荐指数
4
解决办法
3万
查看次数

工程bool比较真假两者,为什么?

示例波纹管编译,但输出相当奇怪:

#include <iostream>
#include <cstring>

struct A
{
    int a;
    char b;
    bool c;
};

int main()
{
    A v;
    std::memset( &v, 0xff, sizeof(v) );

    std::cout << std::boolalpha << ( true == v.c ) << std::endl;
    std::cout << std::boolalpha << ( false == v.c ) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

true
true
Run Code Online (Sandbox Code Playgroud)

有人能解释为什么吗?

如果重要,我使用的是g ++ 4.3.0

c++

21
推荐指数
1
解决办法
1444
查看次数

使用GCC和bool指针的条件运算符的奇怪结果

在下面的代码中,我memset()是一个stdbool.h bool值变量123.(也许这是未定义的行为?)然后我将指向此变量的指针传递给受害者函数,该函数尝试使用条件操作来防止意外值.但是,由于某种原因,GCC似乎完全取消了条件操作.

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

void victim(bool* foo)
{
    int bar = *foo ? 1 : 0;
    printf("%d\n", bar);
}

int main()
{
    bool x;
    bool *foo = &x;
    memset(foo, 123, sizeof(bool));
    victim(foo);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
user@host:~$ gcc -Wall -O0 test.c
user@host:~$ ./a.out 
123

使这个特别恼人的是该victim()函数实际上在库中,如果值大于1则会崩溃.

转载于GCC版本4.8.2-19ubuntu1和4.7.2-5.没有在clang上复制.

c gcc conditional-operator undefined-behavior

18
推荐指数
3
解决办法
684
查看次数

_Bool类型和严格别名

我正在尝试编写一些用于类型安全使用的宏_Bool,然后对我的代码进行压力测试.出于恶意测试的目的,我想出了这个肮脏的黑客:

_Bool b=0;
*(unsigned char*)&b = 42;
Run Code Online (Sandbox Code Playgroud)

鉴于实现上_Bool有1个字节sizeof(_Bool)==1,我不知道这个hack是如何违反C标准的.它不应该是严格的别名违规.

然而,当通过各种编译器运行此程序时,我遇到了问题:

#include <stdio.h>

int main(void)
{
  _Static_assert(sizeof(_Bool)==1, "_Bool is not 1 byte");

  _Bool b=0;
  *(unsigned char*)&b = 42;
  printf("%d ", b);
  printf("%d", b!=0 );

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

(代码依赖于printf隐式默认参数提升int)

某些版本的gcc和clang给出输出42 42,其他版本给出0 0.即使禁用了优化.我原以为是42 1.

似乎编译器假设_Bool只能是1或者0同时它42在第一种情况下快乐地打印.

Q1:这是为什么?上面的代码是否包含未定义的行为?

Q2:可靠性如何sizeof(_Bool)?C17 6.5.3.4完全没有提及_Bool.

c boolean strict-aliasing language-lawyer c11

7
推荐指数
1
解决办法
143
查看次数