delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2012/07/30/12:00:06

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
From: "Rod Pemberton" <do_not_have AT notemailnot DOT cmm>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Upgrading from a bad C compiler
Date: Mon, 30 Jul 2012 11:51:01 -0400
Organization: Aioe.org NNTP Server
Lines: 152
Message-ID: <jv6ad7$vqc$1@speranza.aioe.org>
References: <17d4b525-2c31-4c20-b3c5-a7118343e9a5 AT googlegroups DOT com> <jucp01$p35$1 AT speranza DOT aioe DOT org> <b1f8c389-45f4-43e4-9056-62fc50fc9462 AT googlegroups DOT com> <juh7c1$7hk$1 AT speranza DOT aioe DOT org> <3331145d-900b-4bef-8ad0-f533f0b4a17b AT googlegroups DOT com> <juuseq$j7b$1 AT speranza DOT aioe DOT org> <a7htthFse5U1 AT mid DOT dfncis DOT de> <jv1ect$iv$1 AT speranza DOT aioe DOT org> <83lii3hd5r DOT fsf AT gnu DOT org>
NNTP-Posting-Host: CNsg4fVcCsvs3UaOgZtQCw.user.speranza.aioe.org
X-Complaints-To: abuse AT aioe DOT org
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.2001
X-Notice: Filtered by postfilter v. 0.8.2
X-Newsreader: Microsoft Outlook Express 6.00.2800.2001
X-Priority: 3
X-MSMail-Priority: Normal
Bytes: 7777
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

"Eli Zaretskii" <eliz AT gnu DOT org> wrote in message
news:83lii3hd5r DOT fsf AT gnu DOT org...
> > From: "Rod Pemberton" <do_not_have AT notemailnot DOT cmm>
...

> > sizeof() is clearly adequate for returning the correct
> > sizes of basic types.
>
> It is adequate for any kind of data type.
>

Yes, it's adequate, but not always for what is sometimes needed from any
kind of data type.

> > But, my usage of it is minimal, only where absolutely needed.
>
> This can be said about every feature of every programming language --
> they should be used only when necessary.

Your interpretation of my statement seems to lack restraint and avoidance.
I don't see "absolutely needed" and "necessary" as equivalent.  "Necessary"
could mean whatever was coded by the programmer.  I.e., it may be
"necessary" to use the size of an object, but sizeof() may not be
"absolutely needed" to do that.  E.g., the object's size might be known from
it's declaration, such as for an array, or via strlen() which can be used
for non-strings, or use of the "C struct hack" or from address calculations
on "dummy" structure elements, or fscanf() etc.  Following your description,
one would use sizeof() because it's "necessary" to get the size.  Following
mine, one could use another method since sizeof()'s not "absolutely needed"
in all situations.

> > Why would a C programmer assume sizeof() for a union or struct
> > returns anything other than exactly the "sum of the sizes of the
> > individual elements"?  I'd say that's the most likely expectation of
> > someone using sizeof() on a struct, union, or typedef.  That's what
> > it does for int's, char's, long's, etc.  Yes?  Can C return 7 due to
> > padding for sizeof() of an unsigned long?  (Horrors...)   What about
> > sizeof() of a char?  What if it didn't return one ... ?  If someone
> > takes a sizeof() of a struct that has three unsigned long's, they don't
> > expect some astronomical value because of padding or alignment, e.g.,
> > perhaps returning 64 on 64-bit aligned machine...  Do they? No, of
> > course not.  That's something that is learned.
>
> Try 'sizeof(long double)' some day.  On a x86 machine, a 'long double'
> type is a 80-bit floating point type used to store FP values in FP
> registers, so according to you its sizeof should be 10, right?
>

Storing only 80-bits for a mem80 using x87's FSTP seems reasonable.

No, I've made no claims about what sizeof() should or shouldn't return.
Although, I do have a preference.  I was talking about possible expectations
by others.  I.e., what does 'sizeof()' mean to someone using it?  What do
they expect to get from it?  What 'size of' is expected to be returned?

I specifically stated that people could expect sizeof() to return different
things in different contexts and they can.  They won't be correct, but
that's not the issue.

I also stated that sizeof() actually does return different things in
different contexts.  It does.  It works differently depending on the data
type.  For some data types, it doesn't add padding.  You probably think of
them as not having padding, but it's there for them too.

You do realize that C could've added padding even to simple types.  Yes?
I.e., if there is a list of variables all of type 'long', the first 'long'
could've been padded.  If the alignment size is larger than a 'long', then
all of the long's could've been padded too.  sizeof() could've returned a
padded value for it.  That would be consistent with what sizeof() does for
structs or unions.  Wouldn't it?  Of course, you wouldn't want that, would
you?  No, I wouldn't either.  That's not your expectation, nor mine.  The
point being: a programmer's expectations are important and the expectation
should be consistent.  I'm sure more than a few programmers don't - or
didn't at first - expect padding to be included from sizeof().

Personally, I generally don't care what sizeof() returns since I avoid it.
However, I do need to use it sometimes since it's entirely unavoidable,
i.e., dynamic memory allocation.   So, that comes with the constraint that
simple types are exact and have no padding added to them.

> Now try the sample program at the end of this message.

I ran some other code.

OpenWatcom returns 8 ...

OpenWatcom
long double 8
double 8
float 4

I.e., what 'moral' should you learn about x87?
(See FST or FSTP with mem32, mem64, or mem80)

DJGPP returns 12.

DJGPP
long double 12
double 8
float 4

Can I get 10 if I use '#pragma pack(push,1)' ?

If DJGPP is storing a mem80 for a 'long double' and 10 can never be
returned by sizeof(), then DJGPP's sizeof() is broken.  AISI, the
specification agrees with me.

Sub 3 of 6.5.3.4 of ISO C99 only allows for padding of unions and structs.
Excluding padding for union and structs, there is no provision in ISO C99's
6.5.3.4 section for sizeof() to return storage space *beyond* what is
required for storage of a C type or expression.  According to Sub 2 of
6.5.3.4 of ISO C99, for anything other than a union or struct, sizeof() is
supposed to return the exact size in bytes of the C operand, which can be a
C type or an expression.

So, if the two extra bytes are for padding, it's a violation of Sub 3 since
a 'long double' is not a union or struct, which says only union or struct's
can be padded.

Or, if the two extra bytes are to store something relevant for a 'long
double', say x87's control word, then it's a violation of Sub 2 since by
returning 12 sizeof() is not returning the "size in bytes", i.e., 10, of the
C type as the operand to sizeof() - as is required.  In the case of 12,
sizeof() is returning *more than* the "size in bytes" for the C type as the
operand.  There is no provision for sizeof() to do that.

As a practical matter, yes, if the storage size of a basic type is larger
than it's C type, then sizeof() needs to return a larger value like a struct
or union to ensure proper dynamic allocation.  However, using more space
than is needed for the basic type is definately non-compliant behavior.

> What does it tell you?  What is the morale of this?

FYI, it's "moral" not "morale".  They're different.

If you meant "moral," it tells me you're just being annoying and DJGPP is
broken.  No extra information was added to the conversation by this
diversion from you.


In regards to redefining macro's like sizeof(), the C Rationale says:

"Users cannot expect any meaningful behavior to come about from ...
similar subversions of common sense."


Rod Pemberton





- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019