在文件范围内可变修改的数组

时间:2011-01-25 03:26:37

标签: c

以下代码有什么问题?

#define DELAY_CYCLES ((int)(0.1/0.001))
typedef struct {
    double state_history[N_X][DELAY_CYCLES];
    double foo;
} foo

gcc抱怨:

  

main.h:52:3:警告:在文件范围内修改了'state_history'

是因为int cast因某种原因无法在编译时完成吗?

2 个答案:

答案 0 :(得分:11)

再次编辑

如果你遵循标准的字母,那么是的,你应该避免那里的浮点表达式。在C中,除了转换为整数的浮点常量(例如(int)3.0f)之外,为了进行数组大小计算,浮点表达式在编译时不被视为整型常量表达式。您需要修改定义以避免浮点数并仅使用整数。

为了不成为可变长度数组,数组大小必须是“整数常量表达式”(C99§6.7.5.2/ 4),并且“整数常量表达式”在§6.6/ 6中定义(强调矿):

  

整型常量表达式 96)应具有整数类型,并且只能具有整数常量,枚举常量,字符常量,sizeof表达式的操作数结果是整数常量,浮动常量是转换的直接操作数。整数常量表达式中的转换运算符只能将算术类型转换为整数类型,除非作为sizeof运算符的操作数的一部分。

似乎GCC仅在4.5版中添加了该警告。在4.4及更低版本中,即使使用-Wall -Wextra -ansi -pedantic,它也不会报告该代码的任何警告。但是,为了安全且100%可移植,您应该更改DELAY_CYCLES的定义以避免浮点表达式。

答案 1 :(得分:4)

即使它是一个整数常量表达式,(int)(0.1/0.001)也可以很容易地为99或100,因为值0.10.001 不存在浮点。确定IEEE 754指定的值将需要检查0.1和0.001两者以查看它们是否更接近其上方或下方的邻居,然后实际进行这些邻居的划分 - 或者只是在符合要求的系统上进行检查。然而,这是一个我不想依赖于符合实现以获得正确答案的地方。