ctime and time warnings compiling on OSX - c

I am getting some warnings when compiling a C program on OSX 10.6.5, which seem to be quite critical.
extras.c:15: warning: implicit declaration of function ‘time’
extras.c: In function ‘outlog’:
extras.c:363: warning: implicit declaration of function ‘ctime’
The corresponding lines are as follows:
Lines 13-15:
RANDNUMGEN = gsl_rng_alloc(gsl_rng_taus);
long t1;
(void) time(&t1);
Lines 360-363:
if (LOG==NULL) { LOG=stdout;}
TVAL = time(NULL);
char* TIMESTRING = ctime(&TVAL);
I believe the program was originally written for Linux, so I wonder if there is a difference between time and ctime on the two platforms?

Verify that the C files contains:
#include <time.h>
somewhere around the top.
Also,
long t1;
time(t1);
is pretty lousy code, the argument to time() has type time_t*, so that should read
time_t t1;
time(&t1);

Related

How to get the timezone in C99?

I compile C using the C99 version, and I want to try and output the timezone of the given time.
The IDE I use gives GMT+0 as the timezone, but I want to somehow output it with struct tm.
So I followed the instructions from this answer and made this program:
#include <stdio.h>
#include <time.h>
int main()
{
time_t present = time(NULL);
struct tm now = *localtime(&present);
now.tm_mon += 1;
now.tm_year += 1900;
struct tm t = {0};
localtime_r(&present, &t);
printf("%i/%i/%i %i:%i:%i from %s\n", now.tm_mon, now.tm_mday, now.tm_year, now.tm_hour, now.tm_min, now.tm_sec, t.tm_zone);
}
And it seems like I got 2 errors here:
implicit declaration of function 'localtime_r' is invalid in C99
no member named 'tm_zone' in 'struct tm'
So I checked the IDE Manual, and find that localtime_r actually exists, and is part of the <time.h> library.
So now I'm wondering if the IDE's confused or something. I don't know how to fix it either.
This might get closed as it might "need debugging details", but read more.
Because of this whole situation, how can I get the timezone (maybe even the offset) in C99 and get it to be outputted with printf()?
First, localtime_r is not part of the standard library - it's an extension offered by some implementations, and by default its declaration is not exposed in those implementations. To make it available, you'll have to define the macro _POSIX_SOURCE before including time.h to make it available. An easy way to do that is on the command line, like so:
gcc -o tz -D_POSIX_SOURCE -std=c11 -pedantic -Wall -Werror tz.c
otherwise, just define it in your source before including time.h:
#define _POSIX_SOURCE
#include <stdio.h>
#include <time.h>
Secondly, if all you're interested in is the local time zone then there's an easier way to do this - get the current time:
time_t t = time( NULL );
then use both localtime and gmtime to get the broken down time for the current time zone and UTC:
struct tm *local = localtime( &t );
struct tm *zulu = gmtime( &t );
Then compute the difference between the tm_hour members of local and zulu, and that's your time zone.
int tz = zulu->tm_hour - local->tm_hour;
You'll want to check local->tm_isdst to account for daylight savings, but that should at least get you started.

Bison/Lex segfaults on x86 but runs on arm

I have a problem described in the title. I have an Edify language parser that runs without errors when I building it on arm but fails when I try to use it with x86. I traced segfault to yy_scan_bytes function, more precisely to this code:
YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) {
YY_BUFFER_STATE b;
char * buf;
yy_size_t n;
int i;
/* Get memory for full buffer, including space for trailing EOB's. */
n = _yybytes_len + 2;
buf = (char *) yyalloc(n );
if ( ! buf ) {
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
}
for ( i = 0; i < _yybytes_len; ++i ) {
buf[i] = yybytes[i]; // <==========
}
The full code is here: https://github.com/twaik/edify_x86_failing_code
I've got it from AROMA Installer source.
That's everything I discovered after debug. Thanks.
Trying to build your code gives me these errors:
main.c: In function ‘parse_string’:
main.c:27:5: warning: implicit declaration of function ‘yy_switch_to_buffer’ [-W
implicit-function-declaration]
yy_switch_to_buffer(yy_scan_string(str));
^~~~~~~~~~~~~~~~~~~
main.c:27:25: warning: implicit declaration of function ‘yy_scan_string’ [-Wimplicit-function-declaration]
yy_switch_to_buffer(yy_scan_string(str));
That means that the compiler assumes that yy_switch_to_buffer() and yy_scan_string() return an int, as it does for all functions that are not declared before use (as per the c89 standard). But that is not the case (the first returns void, and the second a pointer (YY_BUFFER_STATE)). Notice that on x86_64, the size of a pointer is not the same as the size of an int.
Adding some band-aid prototypes like
void yy_switch_to_buffer(void*);
void *yy_scan_string(const char*);
to main.c, before their use in parse_string() may stop the segfaulting.
A better fix would be to arrange in the Makefile that the lexer be run with the --header-file=lex-header.h option, and then include lex-header.h from main.c. Or even better, wrap all lex-specific code in some simple functions, and put the prototypes of those functions in a header included from both main.c and the *.l file.

Error with undefined variable defined within an IF statement

When trying to compile the following snippet of code:
#include <stdio.h>
#include <time.h>
void change_a(int * a) {
*a = 1;
return;
}
void main(void) {
int a = 0;
change_a(&a);
if (a) {
time_t start = time(NULL);
}
/* do something that never mentions a */
if (a) {
time_t end = time(NULL);
printf("Time spent = %ld\n", (int) end - start);
}
}
GCC states that the start variable is undefined in the printf line:
$ gcc --version
gcc (Debian 4.8.2-1) 4.8.2
[SNIP]
$ gcc -o test.bin test.c
test.c: In function ‘main’:
test.c:24:44: error: ‘start’ undeclared (first use in this function)
printf("Time spent = %ld\n", (int) end - start);
On the other hand, it compiles and works OK when changing the main function to:
void main(void) {
int a = 0;
time_t start = 0;
change_a(&a);
if (a) {
start = time(NULL);
}
...
Question 1
Am I doing something wrong or is the compiler doing something funny I don't know about?
I think it may be the compiler being too smart and optimizing that piece of code out or having a failure in its heuristics or something. But every other time I've "found compiler bugs" it was always me missing some very obvious error.
So I'd rather intelligent people check this before I accuse other smart people of not being so smart. Specially when the issue also happens without optimization:
$ gcc -O0 -o test.bin test.c
test.c: In function ‘main’:
test.c:24:44: error: ‘start’ undeclared (first use in this function)
printf("Time spent = %ld\n", (int) end - start);
^
test.c:24:44: note: each undeclared identifier is reported only once for each function it appears in
Question 2
I'd also like to know if there is a better way to avoid the compiler error (if not the workaround in the last code snippet). This is kind of obvious if it is my code that is wrong (as the response would include the "correct" code), but I would also like to know how to avoid the error while someone fixes the (alleged) bug in GCC.
In your first example, the start variable is declared inside the scope of the if statement. The variable therefore goes out of scope at the end of the code block (the closing curly brace }). This is definitely not a compiler bug.
Your "workaround" is the correct solution.
See here for a more thorough description of how variable scope works in C/C++ (and many other languages which use C-style scoping).
maybe "start" scope is in
if (a) {
time_t start = time(NULL);
}
start is cannot refernce out of if block

difference between time() and gettimeofday() and why does one cause seg fault

I'm trying to measure the amount of time for a system call, and I tried using time(0) and gettimeofday() in this program, but whenever I use gettimeofday() it seg faults. I suppose I can just use time(0) but I'd like to know why this is happening. And I know you guys can just look at it and see the problem. Please don't yell at me!
I want to get the time but not save it anywhere.
I've tried every combination of code I can think of but I pasted the simplest version here. I'm new to C and Linux. I look at the .stackdump file but it's pretty meaningless to me.
GetRDTSC is in util.h and it does rdtsc(), as one might expect. Now it's set to 10 iterations but later the loop will run 1000 times, without printf.
#include <stdio.h>
#include <time.h>
#include "util.h"
int main() {
int i;
uint64_t cycles[10];
for (i = 0; i < 10; ++i) {
// get initial cycles
uint64_t init = GetRDTSC();
gettimeofday(); // <== time(0) will work here without a seg fault.
// get cycles after
uint64_t after = GetRDTSC();
// save cycles for each operation in an array
cycles[i] = after - init;
printf("%i\n", (int)(cycles[i]));
}
}
The short version
gettimeofday() requires a pointer to a struct timeval to fill with time data.
So, for example, you'd do something like this:
#include <sys/time.h>
#include <stdio.h>
int main() {
struct timeval tv;
gettimeofday(&tv, NULL); // timezone should be NULL
printf("%d seconds\n", tv.tv_secs);
return 0;
}
The long version
The real problem is that gcc is automatically including vdso on your system, which contains a symbol for the syscall gettimeofday. Consider this program (entire file):
int main() {
gettimeofday();
return 0;
}
By default, gcc will compile this without warning. If you check the symbols it's linked against, you'll see:
ternus#event-horizon ~> gcc -o foo foo.c
ternus#event-horizon ~> ldd foo
linux-vdso.so.1 => (0x00007ffff33fe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f56a5255000)
/lib64/ld-linux-x86-64.so.2 (0x00007f56a562b000)
You just happen to be using a function that has a defined symbol, but without the prototype, there's no way to tell how many command-line arguments it's supposed to have.
If you compile it with -Wall, you'll see:
ternus#event-horizon ~> gcc -Wall -o foo foo.c
foo.c: In function ‘main’:
foo.c:2:3: warning: implicit declaration of function ‘gettimeofday’ [-Wimplicit-function-declaration]
Of course, it'll segfault when you try to run it. Interestingly, it'll segfault in kernel space (this is on MacOS):
cternus#astarael ~/foo> gcc -o foo -g foo.c
cternus#astarael ~/foo> gdb foo
GNU gdb 6.3.50-20050815 (Apple version gdb-1822) (Sun Aug 5 03:00:42 UTC 2012)
[etc]
(gdb) run
Starting program: /Users/cternus/foo/foo
Reading symbols for shared libraries +.............................. done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000001
0x00007fff87eeab73 in __commpage_gettimeofday ()
Now consider this program (again, no header files):
typedef struct {
long tv_sec;
long tv_usec;
} timeval;
int main() {
timeval tv;
gettimeofday(&tv, 0);
return 0;
}
This will compile and run just fine -- no segfault. You've provided it with the memory location it expects, even though there's still no gettimeofday prototype provided.
More information:
Can anyone understand how gettimeofday works?
Is there a faster equivalent of gettimeofday?
The POSIX gettimeofday specification

Strange errors using timeval struct and gettimeofday —because of semicolon in #define

I am getting a couple of weird compilation errors. This is for a homework assignment (help is ok). The idea is to implement a program that tests how well the user can hit "enter" once a second. I'm supposed to use gettimeofday to get some time values for each "enter" and then find out what the average time is and standard deviation... I'm trying to do this by checking stdin for '\n' and then if true, using gettimeofday to populate a timeval struct, then store said struct in an array for later use...
The errors I'm getting when compiling (gcc -Wextra homework1.c) are:
homework1.c: In function ‘main’:
homework1.c:19:29: error: expected ‘]’ before ‘;’ token
homework1.c:27:17: error: expected ‘)’ before ‘;’ token
homework1.c:32:4: error: ‘entry_array’ undeclared (first use in this function)
homework1.c:32:4: note: each undeclared identifier is reported only once for each function it appears in
I can't see why I'm getting those first two syntax errors and then I can't understand why "entry_array" is undeclared when I am clearly declaring it in the beginning of "main." Suggestions?
I feel like I'm getting burned by not knowing how to use the timeval struct... Initially I tried to define the struct timeval globally like you would with any other struct but was getting an error about overwriting the definition for struct timeval... Is this because it is defined in the "sys/time.h" library?
Here's the code:
GNU nano 2.2.6 File: homework1.c
//prototypes
int GetAverage(long array[]);
int GetStdDev(long array[]);
//# of keystrokes tracked by user
#define MAX_STROKES 1;
int main(int argv, char ** argc) {
struct timeval entry_array[MAX_STROKES]; //container for tv_usec fields from timeval struct
double average = 0;
double std_deviation = 0;
int count = 0;
printf("This program will test your ability to hit enter every 1 second, for 10 seconds. Ready when yo$
//loop to build array of timeval's
while (count < MAX_STROKES) {
struct timeval time_val;
int input = getc(stdin);
if (input == '\n') {
gettimeofday(&time_val, NULL);
entry_array[count] = time_val;
++count;
}
}
return 0;
}
The problem is the MAX_STROKES macro. As this is homework, I won't tell you exactly what the problem with it is.
This:
#define MAX_STROKES 1; could become a syntax error wherever you use "MAX_STROKES" (it's your job to figure out "why" ;)).
I hope you have this commented out: GNU nano 2.2.6 File: homework1.c
I'm not sure whether your "printf()" is OK: in your cut/paste, it's cut off here: Ready when yo$
I hope you're #includ'ing all the files you need, like "stdio.h" and "time.h"
Did a little research and decided that the MAX_STROKES macro idea I had wasn't quite right. Thanks guys. My guess is that it wasn't standing for what I wanted. I was looking for "int MAX_STROKES = 1"... Was 1 a char by default as it was? I can't quite tell what exactly it was. After reading I decided to use "static const int MAX_STROKES = 1;" instead and it compiled fine.

Resources