Structures, Functions, and PointersOh my

Click For Summary

Discussion Overview

The discussion revolves around the implementation of a C function, localTime(), which is intended to convert UNIX Epoch time into a human-readable format using a defined structure, ExpandedTime. Participants are seeking assistance with coding errors and understanding function prototypes, structure usage, and proper function calls.

Discussion Character

  • Technical explanation
  • Homework-related
  • Debate/contested

Main Points Raised

  • One participant shares code defining a structure, ExpandedTime, and expresses confusion about the function localTime(), which is supposed to return a pointer to an ExpandedTime structure.
  • Another participant points out that localTime() returns a pointer, not the structure itself, and suggests that the error might be in the function body rather than the declaration.
  • Several participants suggest that a missing semicolon after the structure definition could be causing compiler errors.
  • One participant mentions the need to implement the function body for localTime() and suggests calling gettimeofday() within it.
  • Another participant highlights a syntax error in the way a variable is defined and emphasizes the difference between declaring a function and calling it.
  • There is confusion about passing the address of a variable versus the type name, with participants clarifying that the address operator (&) should be used with an instance of the structure, not the type itself.
  • Participants discuss the need to correctly define and call the localTime() function, with one suggesting that the return value should not be ignored.
  • One participant summarizes their understanding of the task, stating that localTime() should convert UNIX Epoch time and store the results in the ExpandedTime structure.

Areas of Agreement / Disagreement

Participants generally agree on the need for proper function declaration and calling conventions, but there remains some confusion about the implementation details and the correct usage of pointers and structures. The discussion does not reach a consensus on the final implementation of the localTime() function.

Contextual Notes

There are unresolved issues regarding the exact implementation of the localTime() function, including how to correctly pass parameters and handle return values. Some participants express uncertainty about the syntax and structure of their code.

xortan
Messages
76
Reaction score
1
Here is some code:

typedef struct ExpandedTime
{
int et_usec;
int et_sec;
int et_min;
int et_hour;
}

ExpandedTime* localTime(ExpandedTime* etime);

Apparently the ExpandedTime* localTime(ExpandedTime* etime) is a function called localTime() that takes a pointer to an ExpandedTime structure which I am calling etime and returns an ExpandedTime structure. I am not understanding how to implement this at all, the compiler keeps telling me I am missing an = sign somewhere. If anyone can help me get through this I have put about 9 hours into this lab so far and there are still 3 other parts to do for it.

Essentially what the lab is doing is taking the Epoch time from UNIX and converting it to a human readable string. I have done the flowcharts and planning for that but its just this structure thing that's confusing the hell out of me.

Thanks for the help!
 
Technology news on Phys.org
These are just declarations, I guess compiler reports the error somewhere in the function body. Not seeing the code it is hard to comment. The only obvious thing is that you need a correct return statement in your function - but it doesn't require an = sign.

Please use [noparse]
Code:
[/noparse] tags when posting sources.
 
xortan said:
Here is some code:

typedef struct ExpandedTime
{
int et_usec;
int et_sec;
int et_min;
int et_hour;
}

ExpandedTime* localTime(ExpandedTime* etime);

Apparently the ExpandedTime* localTime(ExpandedTime* etime) is a function called localTime() that takes a pointer to an ExpandedTime structure which I am calling etime and returns an ExpandedTime structure.
No, localTime returns the address of (a pointer to) an ExpandedTime struct.
xortan said:
I am not understanding how to implement this at all, the compiler keeps telling me I am missing an = sign somewhere. If anyone can help me get through this I have put about 9 hours into this lab so far and there are still 3 other parts to do for it.

Essentially what the lab is doing is taking the Epoch time from UNIX and converting it to a human readable string. I have done the flowcharts and planning for that but its just this structure thing that's confusing the hell out of me.

Thanks for the help!
 
So is localtime() going to a function outside of main() in the .c file? Also is that a proper way to declare that function, the compiler tells me the error is at that line. Also do I need to define the structure and call it etime?
 
Last edited:
Missing semicolon perhaps?
 
Borek said:
Missing semicolon perhaps?

Yup. That's my first guess as well.
You need a semicolon after the closing brace of the struct.
 
I have gotten rid of the compiler error but I am still confused on what that function prototype is. So the file is called fmttime.c which I have another program calling it to print time stamps on a chart plotter. Here is all my code so far

Code:
#include<stdio.h>
#include<sys/time.h>
#include<curses.h>

struct ExpandedTime 
{ 
    int et_usec; 
    int et_sec; 
    int et_min; 
    int et_hour; 
}; 

ExpandedTime etime;                                          //Define Structure

ExpandedTime* localTime(ExpandedTime* etime)     //Function prototype

int main(void) 
{ 
  struct timeval now; 
  struct ExpandedTime *etime; 
  etime = &time; 

   int rc; 
   int sec, min, hour; 

   rc = gettimeofday(&now, NULL); 
   if (rc == 0) 
  { 
     printf("gettimeofday() successful\n\n\n"); 

     sec = now.tv_sec % 60; 
     min = (now.tv_sec / 60) % 60; 
     hour = (now.tv_sec / 3600) % 24; 

     ExpandedTime etime = {0, sec, min, hour}; 

     printf("Hour: %u\t", etime.et_hour); 
     printf("Mintues: %u\t", etime.et_min); 
     printf("Seconds: %u\n", etime.et_sec); 
  } 
  else 
  { 
     printf("gettimeofday() failed, erno = %d\n", errno); 
     return -1; 
   }

   return 0; 

}

So the function localTime() is outside of main and the only part I need to do within that is write those values to the structure? How do I pass things to localTime() to do that?
 
Well, you would still have compiler errors, since there is another semicolon missing after the localTime function.
Furthermore the statement "etime = &time;" appears to contain a typo that should result in another compiler error.

Anyway, as it is, you are not using the function localTime, so it does not do anything useful.

Can it be that the assignment asks you to implement that function yourself?
In that case you should write the function body yourself in which you would call gettimeofday().
And in the main() you should call the localTime function instead of the gettimeofday function to test if it works properly.
 
Im doing this in UNIX so typing this all in and not copying it so I might be missing a semicolon :P So I tried changing it and put most the code into localTime. Here is a section of my new main(), I am just confused on how to properly call that.

Code:
int main(void) 
{ 
   ExpandedTime time; 
   ExpandedTime &etime(time); 
   ExpandedTime* localTime(ExpandedTime* etime); 
   
}

Am I calling this function properly?
 
  • #10
Let's see...

Code:
   ExpandedTime time;
This defines a variable named "time" of the struct type, which is ok.

Code:
   ExpandedTime &etime(time);
In C this is a syntax error, but in C++ this defines a reference-variable named "etime".
What was your intention with it?

Code:
   ExpandedTime* localTime(ExpandedTime* etime);
This declares a function named "localTime", but this is not a call.Consider a function f that takes an integer as argument and returns an integer.
You would implement it as follows (function definition and call in main):
Code:
/* Function definition */
int f(int x)
{
   int y = 2 * x;
   return y;
}

int main()
{
   int a = 3;
   int y;
   int f(int x);  /* This is redundant and would be a prototype declaration of the function f */
   
   y = f(a);     /* This is the proper function call */

   return 0;
}
 
  • #11
So is this a better way?

Code:
int main(void) 
{ 
  struct ExpandedTime *time; 
  time = &ExpandedTime; 
  localTime(time); 

   return 0; 
}

I get compiler error telling me it expected a primary expression before time = &ExpandedTime;
 
  • #12
OK, so I was confusing, it's clearer to me now what you were looking for. Carry on. :)
 
Last edited:
  • #13
xortan said:
So is this a better way?

Code:
int main(void) 
{ 
  struct ExpandedTime *time; 
  time = &ExpandedTime; 
  localTime(time); 

   return 0; 
}

I get compiler error telling me it expected a primary expression before time = &ExpandedTime;

With the ampersand (&) you are taking the address of a variable.
In this case you're trying to do that of ExpandedTime.
However that is the name of a type and not the name of a variable, so this is not allowed.

Your call to localTime(time) is a proper function call now.
Note that you are ignoring the return value, but that is allowed.

It should be like this:

Code:
int main(void) 
{ 
  struct ExpandedTime etime; 
  localTime(&etime); 

   return 0; 
}

Here a variable named "etime" is defined.
And the localTime function is called with the address of "etime" passed as a function parameter.
 
  • #14
localTime() is supposed to take a UNIX Epoch time and convert it to the current time and store those values in the structure ExpandedTime. I am then supposed to use this .c file and call it from another file to print a time stamp on a program I wrote last week that plots graphs.

So I took your suggestion and here is what my code looks like now.

Code:
struct ExpandedTime 
{
  int et_usec; 
  int et_sec; 
  int et_min; 
  int et_hour; 
}; 

ExpandedTime* localTime(ExpandedTime* etime); 

int main(void) 
{ 

  struct ExpandedTime *time; 
  time = &ExpandedTime; 
  ExpandedTime* localTime(ExpandedTime* time); 

  //print hours
  //print mins 
  //print seconds 

  return 0; 

} 

ExpandedTime* localTime(ExpandedTime* etime) 
{ 

  ExpandedTime *etme = (ExpandedTime *)malloc(sizeof(ExpandedTime)); 
  struct timeval now; 

  gettimeofday(&now, NULL); 

  etime->et_sec = now->tv_sec % 60; 
  etime->et_min = (now->(tv_sec / 60)) % 60; 
  etime->et_hour = (now->(tv_sec / 3600)) % 24; 

  return etime; 
}

Here are the associated compiler errors I am getting when I am trying this

Code:
fmttime.c: In function 'int main()':
fmttime.c:19: error: expected primary-expression before ';' token
fmttime.c: In function 'ExpandedTime* localTime(ExpandedTime*)':
fmttime.c:36: error: declaration of 'ExpandedTime* etime' shadows a parameter
fmttime.c:36: error: 'Expanded' was not declared in this scope
fmttime.c:36: error: 'malloc' was not declared in this scope
fmttime.c:41: error: base operand of '->' has non-pointer type 'timeval'
fmttime.c:42: error: base operand of '->' has non-pointer type 'timeval'
fmttime.c:42: error: expected unqualified-id before '(' token
fmttime.c:42: error: 'tv_sec' was not declared in this scope
fmttime.c:43: error: base operand of '->' has non-pointer type 'timeval'
fmttime.c:43: error: expected unqualified-id before '(' token

Thanks for the help everyone, I know I'm n00b but I think I am getting close to it :P
 
  • #15
Thank you I like Serena that seems to be working! Now I just got all the compiler arrows dealing with the ->
 
  • #16
You should drop the line with malloc in it completely.
This makes the parameter etime inaccessible, which should be filled with the values.

The variable "now" is not a pointer but a regular variable (non-pointer type).
This means you should use "." instead of "->" to refer to its fields.

Your parentheses are not quite right, but perhaps you'll see how to fix them.
 
  • #17
As far as your specification goes, the etime value should have been filled outside of the localTime function. So the code in the body which calls gettimeofday I suppose should go in the main body. The localTime function then should convert the passed time in UNIX time to local time, which probably is a silly thing since I assume there's a library somewhere which would do exactly that for you.
 
  • #18
MarcoD said:
As far as your specification goes, the etime value should have been filled outside of the localTime function. So the code in the body which calls gettimeofday I suppose should go in the main body. The localTime function then should convert the passed time in UNIX time to local time, which probably is a silly thing since I assume there's a library somewhere which would do exactly that for you.

I don't think so.
I think the code is exactly as it should be with the modification I mentioned in my last post.

I believe localTime is a function that the OP is supposed to write himself, which he did now.
The etime parameter is an output parameter that is supposed to be filled by the function.
The return value is presumably supposed to be a (redundant) copy of the output parameter (somewhat similar to the standard time() and localtime() functions).
 
  • #19
I like Serena said:
I don't think so.

Your modification was correct but you can see that the parameter passed to the function isn't used. Ah well, forget it. I wouldn't normally write a function this manner; and from the specification I got it was an argument to be converted, not a modifiable argument.
 
  • #20
Also, the first line in your localTime function definition has a typo - etme instead of etime.
Code:
ExpandedTime *etme = (ExpandedTime *)malloc(sizeof(ExpandedTime));
It might be that in your actual code the line was write, but when you retyped it, you made the typo.
 
  • #21
Thank you for the help everyone and for being patient with me :) I got this part of the program working now!
 
  • #22
It never ceases to amaze me how much confusion a newbie in a programming can create.

Stuff you might consider to optimize your code: 1) In a language with manual allocation, determine who gets the responsibility for allocating structures. 2) Write down informal specs of what functions are supposed to do above the prototypes. That manner, not only aren't other people (we) less confused, but it may actually help yourself getting the implementation right.
 
Last edited by a moderator:

Similar threads

Replies
12
Views
2K
  • · Replies 17 ·
Replies
17
Views
3K
Replies
6
Views
2K
Replies
10
Views
2K
  • · Replies 39 ·
2
Replies
39
Views
5K
  • · Replies 11 ·
Replies
11
Views
2K
  • · Replies 6 ·
Replies
6
Views
12K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 10 ·
Replies
10
Views
4K