By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,562 Members | 1,318 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,562 IT Pros & Developers. It's quick & easy.

Can it be done at compile time?

P: n/a
Ark
Hello NG,
I arrange data in structs like
{
members...
uint16_t crc;
more members, maybe...
}
Then I need to save them, up to and including crc, in non-volatile
memory or a file, as the case may be.
The data size I need for type T is offsetof(struct T, crc) +
sizeof(uint16_t).
(Even if there are no more-members, this, depending on alignment, may be
shorter than sizeof(struct T).

The trouble comes when I try to test, at compile time, that I haven't
exceeded the max size of NV memory or of the file.
For expressions involving sizeof, I learned the routine:
#define SIZE ...sum up accordingly...
extern char dummy[(SIZE<=SIZE_MAX)?1:-1];
This won't take offsetof though 'cause it uses pointer type internally
and is not an "integer expression".
Is there any creative way to test the size limit at compile time?

BTW, I believe it is portable to assume that members are before crc and
more-members are after it. Is this correct? (Oh, /assumption/ is
portable, but you know what I mean :)

Thanks
- Ark
Aug 2 '06 #1
Share this Question
Share on Google+
12 Replies


P: n/a

Ark wrote:
Hello NG,
I arrange data in structs like
{
members...
uint16_t crc;
more members, maybe...
}
Then I need to save them, up to and including crc, in non-volatile
memory or a file, as the case may be.
The data size I need for type T is offsetof(struct T, crc) +
sizeof(uint16_t).
(Even if there are no more-members, this, depending on alignment, may be
shorter than sizeof(struct T).
I don't get your question.... but assuming it's something like

1. You want data in a structure
2. You want said data to include a CRC of said data....

Just write a script called from your makefile that generates a .c file
that has a structure in it.

Tom

Aug 2 '06 #2

P: n/a
"Ark" <ak*****@macroexpressions.comwrote in message
news:0I******************************@comcast.com. ..
This won't take offsetof though 'cause it uses pointer type internally and
is not an "integer expression".
Then your implementation is broken. The C standard requires offsetof to be
an integer constant expression:

7.17 Common definitions <stddef.h>
[...]
3 The macros are

NULL

which expands to an implementation-defined null pointer constant; and

offsetof(type, member-designator)

which expands to an integer constant expression that has type size_t, the
value of which is the offset in bytes, to the structure member (designated
by member-designator), from the beginning of its structure (designated by
type). [...]

[Followups restricted to comp.lang.c]
Aug 2 '06 #3

P: n/a
Ark
Wojtek Lerch wrote:
"Ark" <ak*****@macroexpressions.comwrote in message
news:0I******************************@comcast.com. ..
>This won't take offsetof though 'cause it uses pointer type internally and
is not an "integer expression".

Then your implementation is broken. The C standard requires offsetof to be
an integer constant expression:

7.17 Common definitions <stddef.h>
[...]
3 The macros are

NULL

which expands to an implementation-defined null pointer constant; and

offsetof(type, member-designator)

which expands to an integer constant expression that has type size_t, the
value of which is the offset in bytes, to the structure member (designated
by member-designator), from the beginning of its structure (designated by
type). [...]

[Followups restricted to comp.lang.c]

Well, most of the time it is like
#define offsetof(type, member) ((size_t)&((type *)0)->member))
or something to that end.
That ain't good enough for array dimension.

Thanks,

Ark
Aug 2 '06 #4

P: n/a
Ark <ak*****@macroexpressions.comwrites:
I arrange data in structs like
{
members...
uint16_t crc;
more members, maybe...
}
Then I need to save them, up to and including crc, in non-volatile
memory or a file, as the case may be.
The data size I need for type T is offsetof(struct T, crc) +
sizeof(uint16_t).
(Even if there are no more-members, this, depending on alignment, may
be shorter than sizeof(struct T).

The trouble comes when I try to test, at compile time, that I haven't
exceeded the max size of NV memory or of the file.
For expressions involving sizeof, I learned the routine:
#define SIZE ...sum up accordingly...
extern char dummy[(SIZE<=SIZE_MAX)?1:-1];
This won't take offsetof though 'cause it uses pointer type internally
and is not an "integer expression".
Is there any creative way to test the size limit at compile time?
This is a C programming question, not a question about the standard.
Followups redirected to comp.lang.c.
BTW, I believe it is portable to assume that members are before crc
and more-members are after it. Is this correct? (Oh, /assumption/ is
portable, but you know what I mean :)
Yes, struct members are guaranteed to be allocated in their declared
order.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 2 '06 #5

P: n/a
Ark schrieb:
Wojtek Lerch wrote:
>"Ark" <ak*****@macroexpressions.comwrote in message
news:0I******************************@comcast.com ...
>>This won't take offsetof though 'cause it uses pointer type
internally and is not an "integer expression".

Then your implementation is broken. The C standard requires offsetof
to be an integer constant expression:

7.17 Common definitions <stddef.h>
[...]
3 The macros are

NULL

which expands to an implementation-defined null pointer constant; and

offsetof(type, member-designator)

which expands to an integer constant expression that has type size_t,
the value of which is the offset in bytes, to the structure member
(designated by member-designator), from the beginning of its structure
(designated by type). [...]

[Followups restricted to comp.lang.c]
Well, most of the time it is like
#define offsetof(type, member) ((size_t)&((type *)0)->member))
or something to that end.
That ain't good enough for array dimension.
_How_ offetof is implemented is the implementation's problem.
The standard says how offsetof behaves -- and this is what you
can rely on for a conforming implementation.
Reread what Wojtek Lerch wrote and consider

,---
$ cat offsetof.c
#include <stddef.h>

#define SIZE_MAX 9
#define CRC_SIZE(T) (offsetof(T, crc) \
+ sizeof(unsigned short))
#define CHECK(Tag, Limit) \
static int baz_##Tag[CRC_SIZE(struct Tag) < (size_t) (Limit) \
? 1 : -1]

struct foo {
int bar;
unsigned short crc;
};

CHECK(foo, SIZE_MAX);

int main (void)
{
return 0;
}

$ gcc -std=c89 -pedantic -Wall -Wextra -O offsetof.c -c
offsetof.c:15: warning: 'baz_foo' defined but not used

$ splint -checks offsetof.c
Splint 3.1.1 --- 02 May 2003

offsetof.c:15:104: File static variable baz_foo declared but not used
A variable is declared but never used. Use /*@unused@*/ in front of
declaration to suppress message. (Use -varuse to inhibit warning)

Finished checking --- 1 code warning

`---

where my implementation's offsetof is defined in the way you
describe above.
For
#define SIZE_MAX 1
I get an error because of negative array size.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Aug 2 '06 #6

P: n/a
Ark <ak*****@macroexpressions.comwrites:
Wojtek Lerch wrote:
>"Ark" <ak*****@macroexpressions.comwrote in message
news:0I******************************@comcast.com ...
>>This won't take offsetof though 'cause it uses pointer type
internally and is not an "integer expression".
Then your implementation is broken. The C standard requires
offsetof to be an integer constant expression:
7.17 Common definitions <stddef.h>
[...]
3 The macros are
NULL
which expands to an implementation-defined null pointer constant; and
offsetof(type, member-designator)
which expands to an integer constant expression that has type
size_t, the value of which is the offset in bytes, to the structure
member (designated by member-designator), from the beginning of its
structure (designated by type). [...]
[Followups restricted to comp.lang.c]
Well, most of the time it is like
#define offsetof(type, member) ((size_t)&((type *)0)->member))
or something to that end.
That ain't good enough for array dimension.
Read it again. The standard requires offsetof() to expand to an
integer constant expression. If the following:

#include <stddef.h>
void foo(void)
{
struct s {
int a;
int b;
};
int arr[offsetof(struct s, b)];
}

doesn't compile, your compiler is broken. (Possibly a compiler might
need to support additional forms of constant expression to make this
work.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 2 '06 #7

P: n/a
Ark
Keith Thompson wrote:
Ark <ak*****@macroexpressions.comwrites:
>Wojtek Lerch wrote:
>>"Ark" <ak*****@macroexpressions.comwrote in message
news:0I******************************@comcast.co m...
This won't take offsetof though 'cause it uses pointer type
internally and is not an "integer expression".
Then your implementation is broken. The C standard requires
offsetof to be an integer constant expression:
7.17 Common definitions <stddef.h>
[...]
3 The macros are
NULL
which expands to an implementation-defined null pointer constant; and
offsetof(type, member-designator)
which expands to an integer constant expression that has type
size_t, the value of which is the offset in bytes, to the structure
member (designated by member-designator), from the beginning of its
structure (designated by type). [...]
[Followups restricted to comp.lang.c]
Well, most of the time it is like
#define offsetof(type, member) ((size_t)&((type *)0)->member))
or something to that end.
That ain't good enough for array dimension.

Read it again. The standard requires offsetof() to expand to an
integer constant expression. If the following:

#include <stddef.h>
void foo(void)
{
struct s {
int a;
int b;
};
int arr[offsetof(struct s, b)];
}

doesn't compile, your compiler is broken. (Possibly a compiler might
need to support additional forms of constant expression to make this
work.)
Sorry, I just made a fool of myself: offsetof was redefined in my
environment.
Thank you all and sorry again.
- Ark
Aug 2 '06 #8

P: n/a
Ark wrote:
Is there any creative way to test the size limit at compile time?
No, because it would have to be done by the preprocessor, which
doesn't know what types are being used in the program (and thus
does not know their sizes).

I usually let the linker tell me about such things.
Aug 5 '06 #9

P: n/a
In comp.std.c Douglas A. Gwyn <DA****@null.netwrote:
Ark wrote:
Is there any creative way to test the size limit at compile time?
No, because it would have to be done by the preprocessor, which
doesn't know what types are being used in the program (and thus
does not know their sizes).
Huh? Since when is "at compile time" synonymous with "at preprocessing
time"? The compiler can certainly be abused to test assertions at
compile time. The OP himself even demonstrated one way of doing that:
by modulating an array size to become negative if the condition fails.
Sure, the error message will be cryptic, but it's a compile time test
all the same.

The OP's problem apparently was that his compiler's implementation of
the offsetof() macro is broken. Not much can be done about that.

--
Hans-Bernhard Broeker (br*****@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Aug 5 '06 #10

P: n/a
Hans-Bernhard Broeker wrote:
In comp.std.c Douglas A. Gwyn <DA****@null.netwrote:
Ark wrote:
Is there any creative way to test the size limit at compile time?
No, because it would have to be done by the preprocessor, which
doesn't know what types are being used in the program (and thus
does not know their sizes).
Huh? Since when is "at compile time" synonymous with "at preprocessing
time"?
When one is "testing at compile time".
The compiler can certainly be abused to test assertions at compile time.
I assumed he wanted to do something more constructive after testing.
Aug 7 '06 #11

P: n/a
Ark wrote:
>Is there any creative way to test the size limit at compile time?
Douglas A. Gwyn wrote:
>No, because it would have to be done by the preprocessor, which
doesn't know what types are being used in the program (and thus
does not know their sizes).
Hans-Bernhard Broeker wrote:
>Huh? Since when is "at compile time" synonymous with "at preprocessing
time"?
The compiler can certainly be abused to test assertions at compile time.
Douglas A. Gwyn wrote:
When one is "testing at compile time".
I assumed he wanted to do something more constructive after testing.
There are macros in <limits.hthat allow the preprocessor to deduce
primitive type sizes.

Unfortunately, that's about all it can glean from any of the standard
headers and macros. I suggested many years ago that we need more
(standard) macros so that portable code can deal with issues like
alignment, endianness, etc.:
http://david.tribble.com/text/c9xmach.txt

Currently, code that needs this kind of information must rely on
hand-written or automatically generated (e.g., from GNU 'config')
header files, none of which are universal.

-drt

Aug 8 '06 #12

P: n/a
In comp.std.c Douglas A. Gwyn <DA****@null.netwrote:
Hans-Bernhard Broeker wrote:
In comp.std.c Douglas A. Gwyn <DA****@null.netwrote:
Ark wrote:
Is there any creative way to test the size limit at compile time?
No, because it would have to be done by the preprocessor, which
doesn't know what types are being used in the program (and thus
does not know their sizes).
Huh? Since when is "at compile time" synonymous with "at preprocessing
time"?
When one is "testing at compile time".
I had expected you to know better than that. "Compile time" is
divided into translation phases, only the first few of which are
"preprocessing". What the OP wanted to do can't be done in those
phases, but since he actually wanted an assertion, not a an arbitrary
condition test, it *can* be done later, by triggering a compiler error
if the test condition fails:

char dummy_array[(condition)?1:-1];

The compiler can certainly be abused to test assertions at compile time.
I assumed he wanted to do something more constructive after testing.
Why? He clearly wanted just a compile-time assert().

--
Hans-Bernhard Broeker (br*****@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Aug 8 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.