I compiled code on my Mac with the GCC Optimization Flag -O3
on to accelerate the execution time. This perfectly worked on my local machine and lead to a speed increase by 2/3.
However, I tried to compile the code on the Amazon EC2, since I am dealing with a large dataset. Using the -O3
optimization flag causes the following warning
warning: call to ‘__fgets_chk_warn’ declared with attribute warning: fgets called with bigger size than length of destination buffer
In the respective function, a text file is parsed line by line. However, I do not really understand why I end up with the warning. The code of the function reads as follows:
int loadPriceData(const char *filename, double *target) {
char line[40];
FILE *fp;
fp = fopen(filename, "r");
if (fp == NULL) {
return -1;
}
int i = 0;
while (fgets(line, 80, fp) != NULL) {
sscanf(line, "%lf\n", target + i);
i += 1;
}
fclose(fp);
return i; // Return number of elements
}
target
is a pointer to an array with 10000
elements by default. The number of entries is not known in advance, but returned by the function.
You are indeed calling fgets(line, 80, fp)
, but the destination array line
is defined as an array of 40
char. The compiler on the Amazon EC2 is better configured or smarter than yours. This is a real bug if the file contains lines longer than 39 bytes.
Incidentally, the compiler invoked as gcc
on the Mac is usually an instance of clang
. Try gcc --version
.
Note that your program does not check if too much data is read, nor if the sscanf()
conversion succeeds. Both lead to undefined behavior.
Here is a safer version:
int loadPriceData(const char *filename, double *target, int nb_items) {
char line[80];
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
return -1;
}
int i = 0;
while (fgets(line, sizeof line, fp) != NULL) {
if (i < nb_items) {
if (sscanf(line, "%lf", target + i) != 1)
target[i] = 0;
}
i += 1;
}
fclose(fp);
return i; // Return number of elements
}