473,383 Members | 1,958 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Compiler error for "wrong" sized type

The size of a struct can be affected by compiler packing. Suppose you need it to be a
specific value for some reason (e.g., in firmware). How can you get the compiler to
generate an error for the wrong size rather than assert it at run-time? Here is one way,
but I don't know if it's guaranteed to work on any compiler:
1/(sizeof(struct my_struct) == correct_size);

For me, the above produces a compile-time divide-by-zero error for the wrong size. Is
there a better way?

DW
May 12 '06 #1
15 2002
David White said:
The size of a struct can be affected by compiler packing. Suppose you need
it to be a specific value for some reason (e.g., in firmware). How can you
get the compiler to generate an error for the wrong size rather than
assert it at run-time? Here is one way, but I don't know if it's
guaranteed to work on any compiler: 1/(sizeof(struct my_struct) ==
correct_size);

For me, the above produces a compile-time divide-by-zero error for the
wrong size. Is there a better way?


Well, I don't know about "better", but I like this:

char DetectWrongSize[(sizeof(struct my_struct) == correct_size) * 2 - 1];

If the struct is the wrong size, this will yield a negatively sized array,
which is illegal.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 12 '06 #2
David White posted:
The size of a struct can be affected by compiler packing. Suppose you
need it to be a specific value for some reason (e.g., in firmware). How
can you get the compiler to generate an error for the wrong size rather
than assert it at run-time? Here is one way, but I don't know if it's
guaranteed to work on any compiler: 1/(sizeof(struct my_struct) ==
correct_size);

For me, the above produces a compile-time divide-by-zero error for the
wrong size. Is there a better way?

DW

To eliminate the padding (i.e. store each member exactly where you want it),
you could use pointer trickery.

For example, instead of having:

typedef struct Monkey {
int i;
char b;
int j;
};

You could have the following. (It's not pretty, but you could clean it up
and give it a nice interface).
typedef char Monkey[ 2 * sizeof(int) + 1 ];
And then you have functions to access each member:

void SetI( Monkey* const m, int const val )
{
*( (int*)m ) = val;
}

int GetI( const Monkey* const m )
{
return *( (const int*)m );
}

void SetB( Monkey* const m, char const val )
{
*( (char*)m + sizeof(int) ) = val;
}

char GetB( const Monkey* const m )
{
return *( (const char*)m + sizeof(int) );
}

void SetJ( Monkey* const m, int const val )
{
*( (int*)( (char*)m + sizeof(int) + 1 ) ) = val;
}

int GetJ( const Monkey* const m )
{
return *( (const int*)( (const char*)m + sizeof(int) + 1 ) );
}
-Tomás
May 12 '06 #3
"Tomás" <NU**@NULL.NULL> writes:
[...]
To eliminate the padding (i.e. store each member exactly where you want it),
you could use pointer trickery.

For example, instead of having:

typedef struct Monkey {
int i;
char b;
int j;
};

You could have the following. (It's not pretty, but you could clean it up
and give it a nice interface).
typedef char Monkey[ 2 * sizeof(int) + 1 ];
And then you have functions to access each member: [snip] void SetJ( Monkey* const m, int const val )
{
*( (int*)( (char*)m + sizeof(int) + 1 ) ) = val;
}

int GetJ( const Monkey* const m )
{
return *( (const int*)( (const char*)m + sizeof(int) + 1 ) );
}


This access a misaligned int. On many systems, it will cause a trap.

--
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.
May 12 '06 #4

Tomás wrote(in reference to structure padding):

To eliminate the padding (i.e. store each member exactly where you want it),
you could use pointer trickery.


As I read that, the following thought actually fleetingly crossed my
mind:
"That's quite elegant, and eliminates all those annoying padding
problems. Why did C ever bother with the syntactic sugar of structures
and dereferencing members by name?"

I need psychiatric assistance. :)

May 12 '06 #5
Richard Heathfield wrote:
Well, I don't know about "better", but I like this:

char DetectWrongSize[(sizeof(struct my_struct) == correct_size) * 2 -
1];

If the struct is the wrong size, this will yield a negatively sized
array, which is illegal.


Thanks. That's an improvement. Unfortunately, our Hi-Tech compiler doesn't pick it up
because it treats an array size of -1 as unsigned!

DW

P.S. A colleague is terribly disappointed to learn that an array cannot have a negative
size. He thinks it should be allowed, with the valid index range extending from size+1 to
zero inclusive (e.g., -9 to 0 for a size of -10). I asked him what he would expect for a
sizeof of such an array, but he can't decide whether it should be positive or negative.
May 12 '06 #6
David White wrote:
with the
valid index range extending from size+1 to zero inclusive (e.g., -9
to 0 for a size of -10).


Make that: size to -1 inclusive (e.g., -10 to -1 for a size of -10).

DW
May 12 '06 #7
David White wrote:
The size of a struct can be affected by compiler packing. Suppose you need it to be a
specific value for some reason (e.g., in firmware). How can you get the compiler to
generate an error for the wrong size rather than assert it at run-time? Here is one way,
but I don't know if it's guaranteed to work on any compiler:
1/(sizeof(struct my_struct) == correct_size);

For me, the above produces a compile-time divide-by-zero error for the wrong size. Is
there a better way?


normally I speak against the Evil of "#prgama pack" and its ilk. Many
compilers
have extensions that tell the compiler to remove packing from specified
structs.
Such extensions are inherently non-portable and you should be very wary
you
don't assign packed to unpacked or vice versa. But for access to
firmware
especially embedded systems I think it can be justified. Embedded
compilers
may be more likely to support such extensions.
--
Nick Keighley

May 12 '06 #8
David White said:
I asked him what he would expect for a sizeof of such an array, but
he can't decide whether it should be positive or negative.


The size of an array is equal to the number of elements times the size of
each element. Thus, even an array with completely negative indices (were
such an array legal) would have a positive size. Your plane doesn't
suddenly acquire negative weight when you fly across the equator. (It may,
however, flip upside down, depending on who wrote your fbws!)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 12 '06 #9
"Nick Keighley" <ni******************@hotmail.com> wrote in message
news:11**********************@y43g2000cwc.googlegr oups.com...

normally I speak against the Evil of "#prgama pack" and its ilk. Many
compilers
have extensions that tell the compiler to remove packing from specified
structs.
Such extensions are inherently non-portable and you should be very wary
you
don't assign packed to unpacked or vice versa. But for access to
firmware
especially embedded systems I think it can be justified. Embedded
compilers
may be more likely to support such extensions.


I also direct my compiler to use zero padding if I need to create literally
millions of instances of a small struct, e.g., in a recursive puzzle-solving
algorithm that generates new states exponentially and the number needed is
unknown, and may exceed available memory. Undesirable as they may be, such
extensions are useful or necessary in some cases (as are other quite nasty
non-standard practices on occasion).

DW

May 12 '06 #10
David White wrote:
Richard Heathfield wrote:
Well, I don't know about "better", but I like this:

char DetectWrongSize[(sizeof(struct my_struct) == correct_size) * 2 -
1];

If the struct is the wrong size, this will yield a negatively sized
array, which is illegal.

Thanks. That's an improvement. Unfortunately, our Hi-Tech compiler doesn't pick it up
because it treats an array size of -1 as unsigned!

DW

P.S. A colleague is terribly disappointed to learn that an array cannot have a negative
size. He thinks it should be allowed, with the valid index range extending from size+1 to
zero inclusive (e.g., -9 to 0 for a size of -10). I asked him what he would expect for a
sizeof of such an array, but he can't decide whether it should be positive or negative.


Wow! You're a colleague of Paul Dirac?

Hmmm: Dirac's ideas could revolutionize memory management in
C-- (or would it be --C?). If "no memory at all" spontaneously
split into a chunk of allocated memory and a corresponding chunk
of unallocated anti-memory, a program could store data in the
allocated area without needing to call malloc(). Of course, one
would need to be careful: pointer aliasing could cause the memory
and anti-memory to come together and undergo mutual annihilation,
with the resulting, er, Gamma ray constituting an implementation-
defined signal. The task of keeping the allocation separated
from the anti-allocation is probably best left to Maxwell's Nasal
Demon.

--
Eric Sosman
es*****@acm-dot-org.invalid
--
Eric Sosman
es*****@acm-dot-org.invalid
May 12 '06 #11
David White wrote:
[...]
P.S. A colleague is terribly disappointed to learn that an array cannot
have a negative size. He thinks it should be allowed, with the valid
index range extending from size+1 to zero inclusive (e.g., -9 to 0 for
a size of -10). I asked him what he would expect for a sizeof of such
an array, but he can't decide whether it should be positive or negative.


http://astronomy.swin.edu.au/~pbourk...ry/minus1.html

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

May 12 '06 #12
David White wrote:
Richard Heathfield wrote:
Well, I don't know about "better", but I like this:

char DetectWrongSize[(sizeof(struct my_struct) == correct_size) * 2 -
1];

If the struct is the wrong size, this will yield a negatively sized
array, which is illegal.


Thanks. That's an improvement. Unfortunately, our Hi-Tech compiler doesn't pick it up
because it treats an array size of -1 as unsigned!


does it allow multiple case statements with the same value?

switch (0) {
case sizeof(struct my_struct) == correct_size:
case 0:
}

May 12 '06 #13
tedu <tu@zeitbombe.org> wrote:
David White wrote:
Richard Heathfield wrote:
> Well, I don't know about "better", but I like this:
>
> char DetectWrongSize[(sizeof(struct my_struct) == correct_size) * 2 -
> 1];
>
> If the struct is the wrong size, this will yield a negatively sized
> array, which is illegal.


Thanks. That's an improvement. Unfortunately, our Hi-Tech compiler doesn't pick it up
because it treats an array size of -1 as unsigned!


does it allow multiple case statements with the same value?

switch (0) {
case sizeof(struct my_struct) == correct_size:
case 0:
}

Nit: a label reqires a following statement; make it:
switch (0) {
case sizeof(struct my_struct) == correct_size: ;
case 0: ;
}

(Otherwise it's a nice trick, I liked it.)

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
May 12 '06 #14
S.Tobias wrote:
tedu <tu@zeitbombe.org> wrote:
David White wrote:
Richard Heathfield wrote:
> Well, I don't know about "better", but I like this:
>
> char DetectWrongSize[(sizeof(struct my_struct) == correct_size) * 2 -
> 1];
>
> If the struct is the wrong size, this will yield a negatively sized
> array, which is illegal.

Thanks. That's an improvement. Unfortunately, our Hi-Tech compiler doesn't pick it up
because it treats an array size of -1 as unsigned!


does it allow multiple case statements with the same value?

switch (0) {
case sizeof(struct my_struct) == correct_size:
case 0:
}

Nit: a label reqires a following statement; make it:
switch (0) {
case sizeof(struct my_struct) == correct_size: ;
case 0: ;
}

(Otherwise it's a nice trick, I liked it.)


"case 0: ;" is a statement, so the first semicolon isn't necessary. The
second indeed is though.

May 13 '06 #15
"tedu" <tu@zeitbombe.org> wrote in message
news:11**********************@j33g2000cwa.googlegr oups.com...
does it allow multiple case statements with the same value?
I don't know. I'll find out next week.
switch (0) {
case sizeof(struct my_struct) == correct_size:
case 0:
}


Good idea. Incidentally, I had a problem with this rule once. I allowed two
different characters in encoded text to have the same meaning, e.g.,
#define TOKEN_CHAR '#'
#define ALT_TOKEN_CHAR 't'

Since they have the same meaning, the switch that processed them looked like
this:
switch(ch)
{
....
case TOKEN_CHAR:
case ALT_TOKEN_CHAR:
/* process */
break;
....
}

But in some cases I didn't want to allow both characters, so I did this:
#define TOKEN_CHAR '#'
#define ALT_TOKEN_CHAR '#'

The switch then wouldn't compile, but it could have, since there's no clash.

DW

May 13 '06 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: J. Muenchbourg | last post by:
I'm getting an "Arguments are of the wrong type, out of acceptable range, in conflicts with each other " error , pointing to the sql statement in this block: Dim rstime Set rstime =...
7
by: Tim Gaunt | last post by:
Hi, I'm hoping that someone will be able to help me with this one, I'm developing an application which basically inserts a load of data into the database ready for validation at a later date, I...
15
by: Erica | last post by:
I'm getting the following error: ADODB.Recordset error '800a0bb9' Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another. /shop/results.asp, line...
1
by: Jack | last post by:
Hi, I am trying to add a new record to a main page. This page is the processing page to a form. However, I am getting the following error message: Error Type: ADODB.Recordset (0x800A0BB9)...
8
by: the other john | last post by:
Here's my project info first... DB: Access 2000 server: IIS 2003 Here is the error I'm getting... ADODB.Recordset error '800a0bb9' Arguments are of the wrong type, are out of acceptable...
1
by: iam247 | last post by:
Hi I have a web page which receives information from a form (using request.form) and also attempts to look at an Access query to read in recoeds to a variable named rsGroup. When I have the...
1
by: Pradeep83 | last post by:
Hi All, Good Morning Here I am jotdowning my problem I am compiling a .c file in Free BSD 6.0 and exceuting there itself. and i have taken that...
4
by: ravi | last post by:
Hi all, I written and compiled a c++ program using g++ no errors or warning are reported. But when I run it , reporting an error : ERROR: Wrong magic number. What is the reason for this...
5
by: Sheldon | last post by:
Hi Everyone, I have defined a function: struct Transient arrFromHdfNode(HL_NodeList *nodelist, struct Transient retv); and in the code: struct Transient arrFromHdfNode(HL_NodeList...
1
by: thecubemonkey | last post by:
Hi everyone, I'm getting the following error: ADODB.Recordset error '800a0bb9' Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another....
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.