Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何优化;don';t care“;与gcc的争论?_C_Gcc_Optimization - Fatal编程技术网

如何优化;don';t care“;与gcc的争论?

如何优化;don';t care“;与gcc的争论?,c,gcc,optimization,C,Gcc,Optimization,有时函数不使用参数(可能是因为另一个“flags”参数没有启用特定功能) 但是,您必须指定一些内容,因此通常您只需将0放入。但是如果您这样做,并且函数是外部的,gcc将发出代码“真正确保”该参数设置为0 有没有一种方法可以告诉gcc一个函数的特定参数不重要,它可以忽略恰好在参数寄存器中的任何值 更新:有人询问XY问题。这个问题背后的背景是我想在x86_64中实现varargs函数,而不使用编译器varargs支持。当参数在堆栈上时,这是最简单的,因此我声明我的函数首先使用5或6个伪参数,以便最后

有时函数不使用参数(可能是因为另一个“flags”参数没有启用特定功能)

但是,您必须指定一些内容,因此通常您只需将
0
放入。但是如果您这样做,并且函数是外部的,
gcc
将发出代码“真正确保”该参数设置为
0

有没有一种方法可以告诉gcc一个函数的特定参数不重要,它可以忽略恰好在参数寄存器中的任何值


更新:有人询问XY问题。这个问题背后的背景是我想在
x86_64
中实现varargs函数,而不使用编译器varargs支持。当参数在堆栈上时,这是最简单的,因此我声明我的函数首先使用5或6个伪参数,以便最后一个非vararg参数和所有vararg参数都在堆栈上。这很好,只是它显然不是最优的-当查看汇编代码时,很明显,
gcc
正在将调用者中的所有参数寄存器初始化为零。

请不要认真对待下面的答案。这个问题需要一个技巧,你就可以开始了

GCC将有效地将未初始化变量的值视为“不在乎”,所以我们可以尝试利用这一点:

int foo(int x, int y);

int bar_1(int y) {
  int tmp = tmp;  // Suppress uninitialized warnings
  return foo(tmp, y);
}
不幸的是,我的GCC版本仍然怯懦地将
tmp
初始化为零,但您的版本可能更具攻击性:

bar_1:
.LFB0:
  .cfi_startproc
  movl  %edi, %esi
  xorl  %edi, %edi
  jmp   foo
  .cfi_endproc
另一个选项是(ab)使用内联汇编来伪装GCC,使其认为
tmp
已经定义(实际上它没有定义):

使用此GCC,您可以摆脱参数初始化:

bar_2:
.LFB1:
  .cfi_startproc
  movl  %edi, %esi
  jmp   foo
  .cfi_endproc

请注意,内联asm必须紧跟在函数调用之前,否则GCC会认为它必须保留输出值,这将损害寄存器分配。

如果函数是“外部”(即在另一个函数中定义的),那么就不能忽略传递参数。你能详细说明一下你为什么想要这种微观优化吗?你想用这个解决的实际问题和原始问题是什么?请。@Someprogrammerdude当然,原则上你必须传递一个参数,但是如果它是一个寄存器参数,那么传递它就是
O(0)
,如果你只是不初始化它,这就是这个问题的目标。你为什么要在没有
的情况下实现varargs函数?它不能保证工作。你会遇到这样的问题。不要这样做。这样做是倒退的,70年代的编码。如果你想做的话,找一个那个时代的编译器——他们不会抱怨的。这取决于你对“保证”的定义。C标准当然不能保证这一点。GCC也没有。系统V大约有30年的历史了——可能有点老。将其用作“合理假设”并不一定明智。而现代编译器通常不会按照您期望的方式进行编译;他们最大的乐趣是将程序员错误的假设优化为不起作用的代码。你还没有解释为什么你认为避免使用
机制是个好主意。我不明白你在说什么。我只想说,我认为你走错了方向,迟早会遇到问题的。随你的便。你不能说你没有被警告。我相信代码不是关键任务。太棒了!我将使用
asm
选项,因为它很容易填充预处理器宏。虽然有黑客攻击,但它也非常安全-在
gcc
inline
asm
中没有bug,这些语句应该在任何地方都是无害的。@DepresedDaniel Right,不应该让模编译器bug失败。
bar_2:
.LFB1:
  .cfi_startproc
  movl  %edi, %esi
  jmp   foo
  .cfi_endproc