警告:初始化元素在加载时不可计算

时间:2015-02-09 11:30:10

标签: c gcc c89

我无法理解以下场景中的gcc -pedantic输出:

$ gcc -pedantic parse.c -lpopt
parse.c: In function ‘main’:
parse.c:19:7: warning: initializer element is not computable at load time
       { "bps", 'b', POPT_ARG_INT, &speed, 0,
       ^
parse.c:20:7: warning: initializer element is not computable at load time
       "signaling rate in bits-per-second", "BPS" },
       ^
parse.c:27:7: warning: initializer element is not computable at load time
       { "raw", 'r', 0, &raw, 0,
       ^
parse.c:28:7: warning: initializer element is not computable at load time
       "don't perform any character conversions" },
       ^

使用以下C代码(取自here):

$ cat parse.c
#include <popt.h>

int main(int argc, const char *argv[]) {
  char    c;            /* used for argument parsing */
  int     speed = 0;    /* used in argument parsing to set speed */
  int     raw = 0;      /* raw mode? */
  struct poptOption optionsTable[] = {
      { "bps", 'b', POPT_ARG_INT, &speed, 0,
      "signaling rate in bits-per-second", "BPS" },
      { "crnl", 'c', 0, 0, 'c',
      "expand cr characters to cr/lf sequences" },
      { "hwflow", 'h', 0, 0, 'h',
      "use hardware (RTS/CTS) flow control" },
      { "noflow", 'n', 0, 0, 'n',
      "use no flow control" },
      { "raw", 'r', 0, &raw, 0,
      "don't perform any character conversions" },
      { "swflow", 's', 0, 0, 's',
      "use software (XON/XOF) flow control" } ,
      POPT_AUTOHELP
        { NULL, 0, 0, NULL, 0 }
  };
}

使用-ansi-std=c89编译完全相同的代码。为什么-pedantic选项失败?

使用:

$ gcc --version
gcc (Debian 4.9.1-19) 4.9.1
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ apt-cache policy libpopt-dev
libpopt-dev:
  Installed: 1.16-10
  Candidate: 1.16-10
  Version table:
 *** 1.16-10 0
        500 http://ftp.fr.debian.org/debian/ jessie/main amd64 Packages
        100 /var/lib/dpkg/status

2 个答案:

答案 0 :(得分:1)

C89标准中,初始化列表必须是编译时常量表达式,因此警告。但是在C99中,它受到支持。

C89中,您可以执行以下操作:

struct poptOption optionsTable[2];

optionsTable[0] = {"bps", 'b', POPT_ARG_INT, &speed, 0,
  "signaling rate in bits-per-second", "BPS" };
optionsTable[1] = {"crnl", 'c', 0, 0, 'c',
  "expand cr characters to cr/lf sequences" };

答案 1 :(得分:1)

由于在堆栈上分配了变速,因此在编译时不知道其地址。只有执行一次main(),才能知道其地址。变量原始相同。作为任何好的编译器,您的编译器的错误消息并不完全指向错误的元素,并且让您头痛并理解它所抱怨的内容。