#include problem


A

arnuld

I am running into some issue of inclusion of header and I am unable to
understand what is wrong:



fileA.h

#ifndef TEST_HEADERS_A
#define TEST_HEADERS_A

struct myStruct_A
{
int num;
};


void use_print_values(void);

#endif




fileB.h

#ifndef TEST_HEADERS_B
#define TEST_HEADERS_B

#include "fileA.h"

void print_values(struct s1 s);

#endif




fileA.c

#include <stdio.h>
#include "fileA.h"
#include "fileB.h"

void use_print_values(void)
{
struct myStruct_A s;
print_values(s);
}




fileB.c

#include <stdio.h>
#include "fileA.h"
#include "fileB.h"

void print_values(struct myStruct_A s)
{
printf("Num = %d\n", s.num);
}




==================== OUTPUT ======================
[[email protected] C]$ gcc -ansi -pedantic -Wall -Wextra -c fileA.c
In file included from fileA.c:3:
fileB.h:6: warning: ‘struct s1’ declared inside parameter list
fileB.h:6: warning: its scope is only this definition or declaration,
which is probably not what you want
fileA.c: In function ‘use_print_values’:
fileA.c:8: error: type of formal parameter 1 is incomplete
[[email protected] C]$


[[email protected] C]$ gcc -ansi -pedantic -Wall -Wextra -c fileB.c
In file included from fileB.c:3:
fileB.h:6: warning: ‘struct s1’ declared inside parameter list
fileB.h:6: warning: its scope is only this definition or declaration,
which is probably not what you want
fileB.c:6: error: conflicting types for ‘print_values’
fileB.h:6: error: previous declaration of ‘print_values’ was here
[[email protected] C]$
 
Ad

Advertisements

I

Ike Naar

I am running into some issue of inclusion of header and I am unable to
understand what is wrong:

[sni]

fileB.h

#ifndef TEST_HEADERS_B
#define TEST_HEADERS_B

#include "fileA.h"

void print_values(struct s1 s);

Did you mean "struct myStruct_A s" here?
 
B

Ben Bacarisse

arnuld said:
I am running into some issue of inclusion of header and I am unable to
understand what is wrong:

It's not inclusion that is the problem.
fileA.h

#ifndef TEST_HEADERS_A
#define TEST_HEADERS_A

struct myStruct_A
{
int num;
};


void use_print_values(void);

#endif




fileB.h

#ifndef TEST_HEADERS_B
#define TEST_HEADERS_B

#include "fileA.h"

void print_values(struct s1 s);

struct s1 is not defined. Presumably you intended to refer to the
structure defined in fileA.h but that struct myStruct_A.

<snip>
 
A

arnuld

It's not inclusion that is the problem.

fileA.h was incomplete, here it is:

#ifndef TEST_HEADERS_A
#define TEST_HEADERS_A

#include "fileB.h"

struct myStruct_A
{
int num;
};


void use_print_values(void);

#endif

============ OUTPUT ==============
[[email protected] C]$ gcc -ansi -pedantic -Wall -Wextra -c fileB.c
In file included from fileA.h:4,
from fileB.c:2:
fileB.h:6: warning: ‘struct myStruct_A’ declared inside parameter list
fileB.h:6: warning: its scope is only this definition or declaration,
which is probably not what you want
fileB.c:6: error: conflicting types for ‘print_values’
fileB.h:6: error: previous declaration of ‘print_values’ was here
[[email protected] C]$



Header A asks for Header B and Header B asks for Header A, recursive
issue, anyway to solve this ?
 
M

Mark

arnuld said:
#ifndef TEST_HEADERS_A
#define TEST_HEADERS_A

struct myStruct_A
{
int num;
};

Sorry for asking additional questions instead of answering yours: I often
observe the structures containing a single member, often that is an array.
What is the reason for doing so?

Mark
 
Ad

Advertisements

I

Ian Collins

Sorry for asking additional questions instead of answering yours: I often
observe the structures containing a single member, often that is an array.
What is the reason for doing so?

So the array can be copied with one assignment.
 
M

Mark

Ian Collins said:
So the array can be copied with one assignment.

But what exactly do you mean by "can be copied with one assignment" ?

struct my
{
unsigned int foo[6];
};

struct my a1 = { {0xa, 0xb, 0xc, 0x1, 0x2, 0x3} };
struct my a2;

memcpy(&a1, &2, sizeof(struct my));

I still need memcpy, like I would for copying arrays.

Mark
 
I

Ian Collins

Ian Collins said:
So the array can be copied with one assignment.

But what exactly do you mean by "can be copied with one assignment" ?

struct my
{
unsigned int foo[6];
};

struct my a1 = { {0xa, 0xb, 0xc, 0x1, 0x2, 0x3} };
struct my a2;

memcpy(&a1,&2, sizeof(struct my));

I still need memcpy, like I would for copying arrays.

No, just write

a2 = 1a;
 
J

James Kuyper

On 10/ 9/11 04:20 PM, Mark wrote: ....
But what exactly do you mean by "can be copied with one assignment" ?

struct my
{
unsigned int foo[6];
};

struct my a1 = { {0xa, 0xb, 0xc, 0x1, 0x2, 0x3} };
struct my a2;

memcpy(&a1,&2, sizeof(struct my));

memcpy(&a2, &a1, sizeof a2);
No, just write

a2 = 1a;

a2 = a1;
 
Ad

Advertisements

N

Nobody

It destroys the symmetry.
Is there a specific reason to prefer sizeof a2 over sizeof a1 ?

Normally, the two should be equal. If they aren't, you have a problem; the
choice of which one to take the size of has some effect upon how the
problem will manifest. All other factors being equal, reading too much
data is typically less problematic than writing too much data.

If the last parameter is the size of the object pointed to by the first
parameter, memcpy() will always fill the destination exactly (unless it
segfaults due to the read). It will probably fill it with garbage, but it
won't overwrite some adjacent object.

Hopefully this will facilitate identifying the source of the problem
sooner rather than later. I.e. you discover that a2 contains garbage, look
at what touches a2, you've found the problem. Rather than discovering that
z3 contains garbage but finding that nothing which touches z3 looks
suspicious.
 
Ad

Advertisements

J

James Kuyper

It destroys the symmetry.
Is there a specific reason to prefer sizeof a2 over sizeof a1 ?

Well, in this particular, case, as previously mentioned, a2 = a1 is
clearly better than any use of memcpy().

However, in the more general case where a simple assignment statement is
not a viable alternative, I can't really make a strong argument for
"sizeof destination" over "sizeof source". Writing too much is slightly
more likely to be dangerous than reading too much, but I won't claim
that this is a strong argument. However, I strongly prefer either one to
"sizeof(type)". There's two closely related reasons for that preference:
it allows me to change the types of the source and destination (as long
as both are the same) without having to re-write the call to memcpy().
The other, and in my opinion, most important reason, is that I can
confirm that the size is correct just by looking at the memcpy() call, I
don't need to check backwards to the declaration of the destination to
confirm that it is in fact of type 'struct my'.

In principle, it would be better to make sure that both the source and
destination have the same size as that used in the copy; but that would
make the code substantially more clumsy - I don't think it's worth the
effort.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top