如何抑制“警告:控制到达非空函数的结束”

时间:2013-04-10 13:43:05

标签: gcc warnings powerpc eabi

我有一些使用此功能的gcc交叉编译器翻译的PowerPC汇编代码:

uint32_t fill_cache(void)
{
    __asm__ ("addi 3, 0, 0\n");  /* R3 = 0 */
    /* More asm here modifying R3 and filling the cache lines. */
}

,在PowerPC EABI下,返回R3中计算的值。编译时我得到了

foo.c:105: warning: control reaches end of non-void function

有没有办法教gcc实际返回值?或者有没有办法抑制警告(不删除-Wall或添加-Wno- *)?我想非常有选择地仅针对此功能禁止此警告,以便尽可能保持一般警告级别。

不能使此函数返回void,因为调用者需要计算值。

2 个答案:

答案 0 :(得分:13)

解决方案1 ​​:使用diagnostic pragmas,您可以在本地禁止某些诊断检查。在非void函数中抱怨没有返回的特定选项(也由 -Wall 暗示)是 -Wreturn-type 。因此,禁止警告的具体代码是:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wreturn-type"
/* Your code here */
#pragma GCC diagnostic pop

您可以通过使用 -fdiagnostics-show-option 进行编译来找出导致警告的选项。它只会将选项附加到警告消息中。

解决方案2:定义register variable并将其放入所需的寄存器中。请参考inline assembler template中的变量,并生成代码:

uint32_t fill_cache(void)
{
  register uint32_t cacheVal __asm__ ("r3");

  __asm__ __volatile__ ("addi %0, 0, 0" : "=r" (cacheVal));
  /* More code here */

  return cacheVal;
}

volatile 修饰符用于确保指令不被删除或以其他方式受到优化策略的不利影响。

溶液2是优选的,至少有两个原因:

  1. 就标准而言,未返回无空函数的值是未定义的。
  2. 没有压制(新)诊断警告的风险,首先无意压制。

答案 1 :(得分:1)

函数可以声明为naked,在这种情况下编译器不会生成prolog& epilog并假设程序员保留所有必要的寄存器并在返回之前将输出值放入正确的寄存器中。

uint32_t fill_cache(void) __attribute__((naked)); // Declaration
// attribute should be specified in declaration not in implementation

uint32_t fill_cache(void) 
{
    __asm__ ("addi 3, 0, 0\n");  /* R3 = 0 */
    /* More asm here modifying R3 and filling the cache lines. */
}

有点晚了但也许有人会介入这个:)

PS:据我所知,__asm__以及__volatile__std=c89语法。实际上__asm__和{}之间没有区别。 GNU GCC中的asm。但现代的方法是无足轻重的风格:asm volatile

asm_language