相关疑难解决方法(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万
查看次数

切换if-else语句的优点

使用switch语句与使用if30个unsigned枚举的语句的最佳实践是什么,其中大约10个具有预期的操作(目前是相同的操作).需要考虑性能和空间,但并不重要.我已经抽象了代码片段,所以不要因为命名惯例而讨厌我.

switch 声明:

// numError is an error enumeration type, with 0 being the non-error case
// fire_special_event() is a stub method for the shared processing

switch (numError)
{  
  case ERROR_01 :  // intentional fall-through
  case ERROR_07 :  // intentional fall-through
  case ERROR_0A :  // intentional fall-through
  case ERROR_10 :  // intentional fall-through
  case ERROR_15 :  // intentional fall-through
  case ERROR_16 :  // intentional fall-through
  case ERROR_20 :
  {
     fire_special_event();
  }
  break;

  default:
  { …
Run Code Online (Sandbox Code Playgroud)

c++ optimization if-statement switch-statement

162
推荐指数
9
解决办法
10万
查看次数

在x86汇编中将寄存器设置为零的最佳方法是什么:xor,mov或?

以下所有说明都做同样的事情:设置%eax为零.哪种方式最佳(需要最少的机器周期)?

xorl   %eax, %eax
mov    $0, %eax
andl   $0, %eax
Run Code Online (Sandbox Code Playgroud)

optimization performance x86 assembly micro-optimization

109
推荐指数
1
解决办法
4万
查看次数

编译器中的布尔值为8位.对他们的操作是否效率低下?

我正在阅读Agner Fog的" 用C++优化软件 "(特定于英特尔,AMD和威盛的x86处理器),它在第34页说明

布尔变量存储为8位整数,值0表示false,1表示true.布尔变量是超定的,因为所有具有布尔变量作为输入的运算符检查输入是否具有除0或1之外的任何其他值,但是具有布尔值作为输出的运算符不能产生除0或1之外的其他值.布尔变量作为输入效率低于必要的效率.

这今天仍然适用于编译器吗?你能举个例子吗?作者说

如果确定操作数没有除0和1之外的其他值,则可以使布尔运算更有效.编译器没有做出这样的假设的原因是变量可能具有其他值,如果它们是未初始化或来自不明来源.

这是否意味着如果我拿一个函数指针bool(*)()作为示例并调用它,那么对它的操作会产生效率低下的代码?或者是通过取消引用指针或从引用读取然后对其进行操作来访问布尔值的情况?

c c++ optimization x86 boolean

46
推荐指数
2
解决办法
3608
查看次数

x86-64 System V ABI在哪里记录?

x86-64 System V ABI(用于除Windows之外的所有内容)过去常常访问http://x86-64.org/documentation/abi.pdf,但该网站现已脱离互联网.

该文件是否有新的权威主页?

linux assembly x86-64 abi calling-convention

43
推荐指数
2
解决办法
2万
查看次数

在不是地址/指针的值上使用LEA?

我试图了解地址计算指令的工作原理,尤其是leaq命令.然后当我看到leaq用于进行算术运算的例子时,我感到困惑.例如,以下C代码,

long m12(long x) {
return x*12;
}
Run Code Online (Sandbox Code Playgroud)

在组装中

leaq (%rdi, %rdi, 2), %rax
salq $2, $rax
Run Code Online (Sandbox Code Playgroud)

如果我的理解是正确的,那么leaq应该移动任何(%rdi, %rdi, 2)应该2*%rdi+%rdi评估的地址%rax.我感到困惑的是,因为值x存储%rdi在内,这只是内存地址,为什么%rdi乘以3然后左移这个内存地址 2等于x乘以12?是不是当我们%rdi用3时,我们跳到另一个没有值x的内存地址?

c x86 assembly memory-address

4
推荐指数
2
解决办法
4927
查看次数

检查数字是否为偶数

我正在研究低级位黑客,并想为每个黑客编写一个汇编程序。这是我检查数字是否偶数的方法:

is_even:
    # check if an integer is even. 
    # This is the same as seeing if its a multiple of two, i.e., & 1<<n - 1
    # rdi stores the number
    xor %eax, %eax
    test $0b1, %rdi
    setz %al
    ret

_start:
    mov $5, %rdi
    call is_even
Run Code Online (Sandbox Code Playgroud)

有什么方法可以改进上述内容或使其更具可读性?是否可以is_even使用 2 条指令而不是 3 条指令进行检查,因为第一条xor和第二条指令setz似乎可能会转换为一条(如果可能的话)。

x86 assembly bit-manipulation x86-64

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