Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Portability regarding sizeof() function

Reply
Thread Tools

Portability regarding sizeof() function

 
 
Behzad
Guest
Posts: n/a
 
      04-12-2009
Hi all,

I am totally new to the field of portability. One point at the time of
coding i thought would be problem in portability was the use of sizeof
().Now I have read some pages in the net about issues on the
portability. After reading those pages and be assured that sizeof()
can be dangerous,now i am preparing a solution. I was wondering if
there are some best practices regarding sizeof() and Portability at
all.

Can anybody help me to get some solutions and practices?

Thanks in advance,
Behzad
 
Reply With Quote
 
 
 
 
Ben Pfaff
Guest
Posts: n/a
 
      04-12-2009
Behzad <(E-Mail Removed)> writes:

> I am totally new to the field of portability. One point at the time of
> coding i thought would be problem in portability was the use of sizeof
> ().Now I have read some pages in the net about issues on the
> portability. After reading those pages and be assured that sizeof()
> can be dangerous,now i am preparing a solution. I was wondering if
> there are some best practices regarding sizeof() and Portability at
> all.


In what way can sizeof be dangerous? What pages make these
claims?
--
Ben Pfaff
http://benpfaff.org
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      04-12-2009
Behzad <(E-Mail Removed)> writes:
> I am totally new to the field of portability. One point at the time of
> coding i thought would be problem in portability was the use of sizeof
> ().Now I have read some pages in the net about issues on the
> portability. After reading those pages and be assured that sizeof()
> can be dangerous,now i am preparing a solution. I was wondering if
> there are some best practices regarding sizeof() and Portability at
> all.
>
> Can anybody help me to get some solutions and practices?


First off, sizeof is an operator, not a function.

I'm not sure what you mean when you say that "sizeof() can be
dangerous". For any type bigger than char, applying sizeof to that
type will give you an implementation-defined result. It's guaranteed
to be the actual size in bytes of that type, but that actual size can
vary from one implementation to another. For example, sizeof(int)
might be 2 on one system, 4 on another, or even 1 (if CHAR_BIT >= 16,
which is common for DSPs).

There is nothing inherently dangerous about the sizeof operator. It
can be used in dangerous ways, but so can any feature of any language.

Can you be more specific about your concerns?

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      04-12-2009
Behzad wrote:
> Hi all,
>
> I am totally new to the field of portability. One point at the time of
> coding i thought would be problem in portability was the use of sizeof
> ().Now I have read some pages in the net about issues on the
> portability. After reading those pages and be assured that sizeof()
> can be dangerous,now i am preparing a solution. I was wondering if
> there are some best practices regarding sizeof() and Portability at
> all.
>
> Can anybody help me to get some solutions and practices?


Appropriate use of sizeof is essential to writing portable code. Example:

struct tm *t = malloc(sizeof *t);

Would you care to suggest a more portable way of doing that which
doesn't involve use of the sizeof operator?

Inappropriate use of sizeof can be dangerous, but then so can
inappropriate use of just about any other feature of C.
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      04-13-2009
James Kuyper wrote:
>

.... snip ...
>
> Appropriate use of sizeof is essential to writing portable code.
> Example:
> struct tm *t = malloc(sizeof *t);
>
> Would you care to suggest a more portable way of doing that which
> doesn't involve use of the sizeof operator?
>
> Inappropriate use of sizeof can be dangerous, but then so can
> inappropriate use of just about any other feature of C.


Nit. I don't think that works. When sizeof is executed t has not
yet been defined. I think it awaits the final semi.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      04-13-2009
CBFalconer <(E-Mail Removed)> writes:

> James Kuyper wrote:
>>

> ... snip ...
>>
>> Appropriate use of sizeof is essential to writing portable code.
>> Example:
>> struct tm *t = malloc(sizeof *t);
>>
>> Would you care to suggest a more portable way of doing that which
>> doesn't involve use of the sizeof operator?
>>
>> Inappropriate use of sizeof can be dangerous, but then so can
>> inappropriate use of just about any other feature of C.

>
> Nit. I don't think that works. When sizeof is executed t has not
> yet been defined. I think it awaits the final semi.


That is not so. I can't find the place where the standard states that
an identifier is defined from the declarator onwards, but that has
always been my understanding. I.e. even

char c, *cp = &c;

is valid.

If you are right an I am wrong, I am in good company. gcc (and every
other compiler I remember using) prints the size of one int here, not
two:

#include <stdio.h>

int i[2];

int main(void)
{
int i = sizeof i;
printf("%d\n", i);
return 0;
}

[The reason I am so sure about what compilers used to do is not a
stellar one; I used to like to write code like this:

char buffer[SOME_SIZE], *bp = buffer;

when I needed some space and a pointer into it. I would never do that
now, of course!]

--
Ben.
 
Reply With Quote
 
Behzad
Guest
Posts: n/a
 
      04-13-2009
Sorry for late response.

Maybe instead of using 'dangerous', i should use another word!

Anyway, when Let's explain more with an example:

/*-------------------------------------------------------*/
void somefunc(u8* resp,u8* buff)
{
u8* ptr = buff;

ptr = *(int*)&resp[4];
ptr += sizeof(float);

ptr = *(int*)&resp[12];
ptr += sizeof(int);

ptr = *(int*)&resp[16];
ptr += sizeof(short);

}
/*-------------------------------------------------------*/

The above example should be able to run on x86 or ARM machine.Each
machine could have Linux or Windows(XP,CE,etc...) installed on.
so my concerns are the above codes that are ( in my opinion) highly
dependent on the machine and OS implementations.
Do also include Big-endian and Little-endian issues.

Behzad
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-13-2009
CBFalconer <(E-Mail Removed)> writes:
> James Kuyper wrote:
>>

> ... snip ...
>>
>> Appropriate use of sizeof is essential to writing portable code.
>> Example:
>> struct tm *t = malloc(sizeof *t);
>>
>> Would you care to suggest a more portable way of doing that which
>> doesn't involve use of the sizeof operator?
>>
>> Inappropriate use of sizeof can be dangerous, but then so can
>> inappropriate use of just about any other feature of C.

>
> Nit. I don't think that works. When sizeof is executed t has not
> yet been defined. I think it awaits the final semi.


Yes, it does work (though it took me a while to find the section in
the standard that proves it).

The object exists even before the declaration is reached. C99 6.2.4p4-5:

An object whose identifier is declared with no linkage and without
the storage-class specifier static has _automatic storage
duration_.

For such an object that does not have a variable length array
type, its lifetime extends from entry into the block with which it
is associated until execution of that block ends in any way.

But the real question is the scope. C99 6.2.1p7 says:

Structure, union, and enumeration tags have scope that begins just
after the appearance of the tag in a type specifier that declares
the tag. Each enumeration constant has scope that begins just
after the appearance of its defining enumerator in an enumerator
list. Any other identifier has scope that begins just after the
completion of its declarator.

In the declaration above:

struct tm *t = malloc(sizeof *t);

the declarator is ``*t'', the scope of t begins before the "=", and
the initializer is valid.

Incidentally, the fact that the lifetime of an automatic object starts
on entry to the block, before the declaration itself is reached, has
some interesting, though probably not very useful, consequences.

#include <stdio.h>
int main(void)
{
int i;
for (i = 0; i <= 1; i ++) {
int *foo_addr;
if (i == 1) {
printf("foo isn't visible yet, but its value is %d\n", *foo_addr);
}
int foo = 42;
if (i == 0) {
foo_addr = &foo;
}
}
return 0;
}

The output is:

foo isn't visible yet, but its value is 42

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      04-13-2009
Keith Thompson <(E-Mail Removed)> writes:

> Incidentally, the fact that the lifetime of an automatic object starts
> on entry to the block, before the declaration itself is reached, has
> some interesting, though probably not very useful, consequences.
>
> #include <stdio.h>
> int main(void)
> {
> int i;
> for (i = 0; i <= 1; i ++) {
> int *foo_addr;
> if (i == 1) {
> printf("foo isn't visible yet, but its value is %d\n", *foo_addr);
> }
> int foo = 42;
> if (i == 0) {
> foo_addr = &foo;
> }
> }
> return 0;
> }


I think you're missing an important fact here. The block that
starts on the line of the "for" loop is exited just before i++ is
evaluated, and then it is re-entered in the second iteration of
the loop. Therefore, the value of foo_addr is indeterminate when
*foo_addr is evaluated during the second iteration, and therefore
this code yields undefined behavior.
--
"...Almost makes you wonder why Heisenberg didn't include postinc/dec operators
in the uncertainty principle. Which of course makes the above equivalent to
Schrodinger's pointer..."
--Anthony McDonald
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-13-2009
Ben Pfaff <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> writes:
>> Incidentally, the fact that the lifetime of an automatic object starts
>> on entry to the block, before the declaration itself is reached, has
>> some interesting, though probably not very useful, consequences.
>>
>> #include <stdio.h>
>> int main(void)
>> {
>> int i;
>> for (i = 0; i <= 1; i ++) {
>> int *foo_addr;
>> if (i == 1) {
>> printf("foo isn't visible yet, but its value is %d\n", *foo_addr);
>> }
>> int foo = 42;
>> if (i == 0) {
>> foo_addr = &foo;
>> }
>> }
>> return 0;
>> }

>
> I think you're missing an important fact here. The block that
> starts on the line of the "for" loop is exited just before i++ is
> evaluated, and then it is re-entered in the second iteration of
> the loop. Therefore, the value of foo_addr is indeterminate when
> *foo_addr is evaluated during the second iteration, and therefore
> this code yields undefined behavior.


You're right, good catch.

(It happened to "work" because both instances of foo, and of foo_addr,
happen to have the "same" address. I put "same" in quotes because the
addresses of the two instances can't be compared without invoking UB.)

I could construct an example of the same thing that actually works
using a goto, but I don't think I'll bother.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
portability problem with a function returning a struct Army1987 C Programming 19 05-19-2007 10:07 PM
Portability of strstr() function OzBob C Programming 5 12-27-2005 04:48 PM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
Portability Francisco Rodriguez VHDL 2 01-23-2004 02:17 PM
code portability and function call serialisation. Lefevre C++ 1 11-12-2003 04:28 PM



Advertisments