2013-04-10 124 views
5

我有翻译与此功能的gcc交叉编译器的一些PowerPC汇编代码:如何抑制“警告:控制到达非void函数结束”

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。

回答

12

解决方案1 ​​:与diagnostic pragmas您可以在本地禁止某些诊断检查。具体选项(-Wall)暗示在非无效函数中不返回的具体选项是-Wreturn型。因此,特定的代码来抑制警告:

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

你可以找出哪些选项是与-fdiagnostics出现选项编译引起警告。它只会将该选项附加到警告消息。

解决方案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; 
} 

挥发性改性剂是确保该指令不被除去或以某种其他方式被优化策略不期望的影响。

解决方案2是优选的至少有两个原因:

  1. 无返回非void函数的值尽可能的标准是关心未定义。
  2. 没有压制(新)诊断警告的风险,首先无意压制。
1

函数可以被声明为naked,在这种情况下,编译器不会生成序言&结尾并会认为程序员保留了所有必要的寄存器和返回之前把产值为正确的寄存器(S)。

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语法。实际上,GNU GCC中的__asm__ & asm没有区别。但现代的做法是强调风格:asm volatile

asm_language

相关问题