我的代码的一部分出了问题,在一些迭代之后似乎将NaN读作结构的double
的值。我想我发现了错误,但我仍然想知道为什么gcc(带有busybox的嵌入式Linux上的版本3.2.3)没有警告我。以下是代码的重要部分:
用于通过USB获取数据的函数的c文件及其标题:
// usb_control.h
typedef struct{
double mean;
short *values;
} DATA_POINTS;
typedef struct{
int size;
DATA_POINTS *channel1;
//....7 more channels
} DATA_STRUCT;
DATA_STRUCT *create_data_struct(int N); // N values per channel
int free_data_struct(DATA_STRUCT *data);
int aqcu_data(DATA_STRUCT *data, int N);
带有辅助函数的c和头文件(math,bitshift等等):
// helper.h
int mean(DATA_STRUCT *data);
// helper.c (this is where the error is obviously)
double mean(DATA_STRUCT *data)
{
// sum in for loop
data->channel1->mean = sum/data->N;
// ...7 more channels
// a printf here displayed the mean values corretly
}
主文件
// main.c
#include "helper.h"
#include "usb_control.h"
// Allocate space for data struct
DATA_STRUCT *data = create_data_struct(N);
// get data for different delays
for (delay = 0; delay < 500; delay += pw){
acqu_data(data, N);
mean(data);
printf("%.2f",data->channel1->mean); // done for all 8 channels
// printf of the mean values first is correct. Than after 5 iterations
// it is always NaN for channel1. The other channels are displayed correctly;
}
没有段错误或任何其他错误行为,只是主文件中channel1的NaN。
找到错误后,这并不容易,当然是东方修复。 mean(){}
的返回类型在定义中是错误的。而不是double mean()
,它必须是原型定义的int mean()
。当所有函数都放在一个文件中时,gcc警告我有一个函数mean()
的重新定义。但是当我单独编译每个c文件然后链接它们之后,gcc似乎错过了。
所以我的问题就是。为什么我没有得到任何警告,即使没有gcc -Wall?或者是否还有另一个隐藏的错误,现在只是没有引起问题?
此致 基督教
答案 0 :(得分:3)
当单独编译每个.c
文件时,编译器知道的唯一信息就是您给出的函数原型。
因为每个文件都是单独编译的,所以main.c
的编译器进程无法知道mean
中helper.c
的定义是错误的。
编译.c
文件后,签名将被剥离,因此链接器无法知道mean
是错误的。
一个简单的修复程序总是包含实现.h
文件中的接口.c
文件
// in helper.c:
#include "helper.h"
double mean(DATA_STRUCT *data);
然后helper.c
的编译过程会注意到不一致的类型并警告你。
答案 1 :(得分:0)
平均值通常是实际值,所以双倍就可以了。在这里,您将mean
定义为返回double,但原型显示为int mean(...)
。
gcc可以意识到存在重新定义这一事实的唯一方法是,如果重新定义是真实发生的......当你单独编译文件时可能会丢失平均原型......它没有显示在你的代码片段中至少:你应该把helper.h也包含在helper.c中。这样做,gcc -c helper.c
必须给您一个警告。我有gcc 4.3.2,但我几乎可以肯定你的版本也必须如此。在主要内容中,您只需使用mean
,因此此处gcc 信任 helper.h
中的内容。当你链接时,没有关于参数大小和返回值的更多信息,并且会发生不好的事情(比如将int作为double读取)。
另一个细节:你说你得到一个结构的int的NaN ......好吧,在结构中有一个double,而int不能是NaN!