Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question about platform independent code and ANSI C compliant code

43 views
Skip to first unread message

Joe

unread,
Jun 1, 2010, 5:32:32 PM6/1/10
to
Hi,

I am going to implement an algorithm in ANSI C. I also have to
provide an API for the algorithm.

I am using Bloodsheed's Dev-C++ (ver. 4.9.9.2) IDE and I
added the compiler command -ansi in "Compiler Options" and
changed "Support all ANSI standard C programs" from "No"
to "Yes".

Is the above sufficient to ensure that my code complies with the ANSI C
standard?


If some hardware platform comes with a C-compiler, how do I ensure
that my code can be compiled on that platform? Is it enough that my
code is ANSI C compliant?

How do I ensure that variables which must have a bit width of 16bit,
actually compiles into 16bit wide variables (platform independent types!) ?

Is there some header file I can include in my project which will give me
macros like UINT16 and SINT16 such that

SINT16 x;

always will compile into a signed, 16bit variable ?

Dann Corbit

unread,
Jun 1, 2010, 6:13:32 PM6/1/10
to
In article <4c057c73$0$279$1472...@news.sunsite.dk>, J...@NoSpammers.Com
says...

>
> Hi,
>
> I am going to implement an algorithm in ANSI C. I also have to
> provide an API for the algorithm.
>
> I am using Bloodsheed's Dev-C++ (ver. 4.9.9.2) IDE and I
> added the compiler command -ansi in "Compiler Options" and
> changed "Support all ANSI standard C programs" from "No"
> to "Yes".
>
> Is the above sufficient to ensure that my code complies with the ANSI C
> standard?

Possibly. I guess it is the GCC compiler. If that is the case, then I
would recommend:
-W -Wall -ansi -pedantic

> If some hardware platform comes with a C-compiler, how do I ensure
> that my code can be compiled on that platform? Is it enough that my
> code is ANSI C compliant?

The C compiler for that machine must support the same ANSI/ISO C
standard. For instance, C89 or C99.

> How do I ensure that variables which must have a bit width of 16bit,
> actually compiles into 16bit wide variables (platform independent types!) ?

C99 has types for such a guarantee. C89 only has guarantees for "at
least".



> Is there some header file I can include in my project which will give me
> macros like UINT16 and SINT16 such that
>
> SINT16 x;
>
> always will compile into a signed, 16bit variable ?

Even with C99, exact width types are optional.

What is it that you are really trying to accomplish?

Pascal J. Bourguignon

unread,
Jun 1, 2010, 6:34:15 PM6/1/10
to
"Joe" <J...@NoSpammers.Com> writes:

Yes. Have a look at the least types in stdint.h eg. uint_least16_t
will allow you to store at least 16 bits, from 0 to UINT_LEAST16_MAX.


> SINT16 x;
>
> always will compile into a signed, 16bit variable ?

Into a signed variable yes, but 16-bit, no, not always. Sometimes it
will be a 17-bit variable, sometimes a 24-bit variable, sometimes a
29-bit variable, sometimes a 32-bit-variable, etc.

--
__Pascal Bourguignon__ http://www.informatimago.com/

Joe

unread,
Jun 1, 2010, 6:43:57 PM6/1/10
to

> What is it that you are really trying to accomplish?

I just want to be absolutely sure that variables which I want to
be N bit wide always will be compiled into N bit wide variables
independent of platform. No reason to have 16-bit signed values
suddenly being stored in 32-bit variables.

I want to implement a fixed-point, digital filter which is portable.
The filter must work in the same way no matter which platform it is compiled
on as long
as the platform comes with an ANSI C compliant compiler.

I am using the typedefs in stdint.h.

Pascal J. Bourguignon

unread,
Jun 1, 2010, 7:22:05 PM6/1/10
to
"Joe" <J...@NoSpammers.Com> writes:

>> What is it that you are really trying to accomplish?
>
> I just want to be absolutely sure that variables which I want to
> be N bit wide always will be compiled into N bit wide variables
> independent of platform. No reason to have 16-bit signed values
> suddenly being stored in 32-bit variables.

Yes there are very good reason why it might be so.

It may be a 21-bit or 24-bit processor (eg a DSP).

Or even if it's a 32-bit processor, it may not be a byte-addressing
one, perhaps it can only address words, and having a 32-bit wide data
bus, it cannot load less than 32-bit at once.

If both cases, if you wanted to use only 16-bits to store your data,
you would have to pack these bits in the larger word, and accesses to
your 16-bit variable would be at least one order of magnitude slower
than if you just used the 21-bit, 24-bit, 32-bit or whatever word.

Even on computers with byte addressable memory, it is usually NOT
slower to load or store 32-bit than 16-bit. (Well, actually to store
16-bit, if the word where they are is not in the cache, it would be
slower, since it would have to load the 32-bit first in the cache,
before being able to store back the 32-bits).


Then, you may have a C compiler targetting a machine that is not even
binary-bit-based, (eg. Knuth's MIX).


> I want to implement a fixed-point, digital filter which is portable.
> The filter must work in the same way no matter which platform it is
> compiled on as long
> as the platform comes with an ANSI C compliant compiler.
>
> I am using the typedefs in stdint.h.

Mind the fast types too. They often will definitely be bigger than
the least types.

Dann Corbit

unread,
Jun 1, 2010, 7:27:09 PM6/1/10
to
In article <4c058d33$0$283$1472...@news.sunsite.dk>, J...@NoSpammers.Com
says...

>
> > What is it that you are really trying to accomplish?
>
> I just want to be absolutely sure that variables which I want to
> be N bit wide always will be compiled into N bit wide variables
> independent of platform. No reason to have 16-bit signed values
> suddenly being stored in 32-bit variables.

I think that probably you are more interested in portability of function
than portability of storage.



> I want to implement a fixed-point, digital filter which is portable.
> The filter must work in the same way no matter which platform it is compiled
> on as long
> as the platform comes with an ANSI C compliant compiler.
>
> I am using the typedefs in stdint.h.

Keep in mind that some of the typedefs in stdint.h are optional and also
that stdint.h is only guaranteed to be present for C99 compilers.

The use of bit fields will probably suit your needs.

To read and write them you will need a bit i/o method of some kind, or
convert to text.

Peter Nilsson

unread,
Jun 1, 2010, 11:01:03 PM6/1/10
to
"Joe" <J...@NoSpammers.Com> wrote:
> > What is it that you are really trying to accomplish?
>
> I just want to be absolutely sure that variables which I
> want to be N bit wide always will be compiled into N bit
> wide variables independent of platform.

Then you're not writing maximally portable code. All you need
are variables that are _at least_ N bits wide.

> No reason to have 16-bit signed values suddenly being
> stored in 32-bit variables.

Why bother writing 'ANSI C' code if you're going to
exclude the plethora of implementations that don't offer
precise 16-bit wide integers?

> I want to implement a fixed-point, digital filter which
> is portable.

Fine, but you don't need a precise width type to do that.

--
Peter

bart.c

unread,
Jun 3, 2010, 5:28:15 AM6/3/10
to

"Peter Nilsson" <ai...@acay.com.au> wrote in message
news:621bcbad-9ffc-41a2...@z15g2000prh.googlegroups.com...

> "Joe" <J...@NoSpammers.Com> wrote:
>> > What is it that you are really trying to accomplish?
>>
>> I just want to be absolutely sure that variables which I
>> want to be N bit wide always will be compiled into N bit
>> wide variables independent of platform.
>
> Then you're not writing maximally portable code. All you need
> are variables that are _at least_ N bits wide.
>
>> No reason to have 16-bit signed values suddenly being
>> stored in 32-bit variables.
>
> Why bother writing 'ANSI C' code if you're going to
> exclude the plethora of implementations that don't offer
> precise 16-bit wide integers?

In:

unsigned short a;
int b=123456;
a=b;

'a' may end up as 57920 on some machines, and likely 123456 on others. It
seems reasonable to be able to request 'a' to be exactly 16-bits on any
machine, whether that is natural for the architecture on not.

--
Bartc

Pascal J. Bourguignon

unread,
Jun 3, 2010, 6:06:03 AM6/3/10
to
"bart.c" <ba...@freeuk.com> writes:

You can indeed request it:

a=0xffff & b;

but you cannot expect that unsigned short is such a request.

I hope you know the difference between = and ≥.

Richard Heathfield

unread,
Jun 3, 2010, 6:50:35 AM6/3/10
to
bart.c wrote:
>
<snip>

> It seems reasonable to be able to request 'a' to be exactly 16-bits on
> any machine, whether that is natural for the architecture on not.

I'm not entirely convinced that that /is/ a reasonable request. It is
perfectly reasonable to ask for it to be *at least* 16 bits.

How, precisely, would you implement your exactly-16-bit type on a
machine whose natural word size is 64? Such a machine does exist, and C
implementations for it have to jump through all kinds of crazy hoops to
give programmers the 8-bit char they expect. I would not like to be the
one to tell the compiler team "well done lads, but now there's this
bloke on Usenet who wants 16-bit short ints..."

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

bart.c

unread,
Jun 3, 2010, 7:42:23 AM6/3/10
to

"Richard Heathfield" <r...@see.sig.invalid> wrote in message
news:2qmdnQNJioRrFZrR...@bt.com...

> bart.c wrote:
>>
> <snip>
>
>> It seems reasonable to be able to request 'a' to be exactly 16-bits on
>> any machine, whether that is natural for the architecture on not.
>
> I'm not entirely convinced that that /is/ a reasonable request. It is
> perfectly reasonable to ask for it to be *at least* 16 bits.

I think asking for so many bits is reasonable. Requesting a specific range
(such as 32 .. 95) less so, unless that is a feature of the type system
(thinking Pascal and Ada here).

> How, precisely, would you implement your exactly-16-bit type on a machine
> whose natural word size is 64?

(Presumably, where the addressing is also in 64-bits words.)

It isn't really difficult. My first machine was 36-bits and I routinely used
18-bit data sizes.

And I'm implementing a language at the moment (for a byte-addressed machine,
but similar challenges) where any bit-width can be specified:

[]bit:3 x # dynamic array of 3-bit-wide unsigned ints

This is a bit harder than a regular byte-array (especially getting pointers
and slices to work properly), but nothing to write home about.

> Such a machine does exist, and C implementations for it have to jump
> through all kinds of crazy hoops to give programmers the 8-bit char they
> expect. I would not like to be the one to tell the compiler team "well
> done lads, but now there's this bloke on Usenet who wants 16-bit short
> ints..."

They should have done it properly, then there would have been support for
8,16 and 32-bits with little extra effort.

If an application needs a huge array of numbers, that can fit into 16 bits
but not into 8, then, no matter how much memory is available, a 16-bit array
will only ever use a quarter of the memory required by a 64-bit array (and
the reduced memory access will likely compensate for the shifting and
masking overheads).

--
Bartc

Ben Bacarisse

unread,
Jun 3, 2010, 7:58:50 AM6/3/10
to
"bart.c" <ba...@freeuk.com> writes:

In a rather limited way, you can: you can use a 16-bit wide bit-field.
I suppose a conforming C compiler may be permitted to refuse to allocate
such a bit-field but that seems to stretch the letter of the law beyond
what is reasonable.

There are a lot of things you can't do with bit-fields, but they do
provide automatically masked and promoted integer arithmetic. On
balance, though, I'd write the code to use "at least 16 bits" and put
the masks in myself.

--
Ben.

bart.c

unread,
Jun 3, 2010, 8:55:53 AM6/3/10
to

"Ben Bacarisse" <ben.u...@bsb.me.uk> wrote in message
news:0.fafda0c28fab87afab6f.2010...@bsb.me.uk...
> "bart.c" <ba...@freeuk.com> writes:

>> unsigned short a;
>> int b=123456;
>> a=b;
>>
>> 'a' may end up as 57920 on some machines, and likely 123456 on
>> others. It seems reasonable to be able to request 'a' to be exactly
>> 16-bits on any machine, whether that is natural for the architecture
>> on not.
>
> In a rather limited way, you can: you can use a 16-bit wide bit-field.
> I suppose a conforming C compiler may be permitted to refuse to allocate
> such a bit-field but that seems to stretch the letter of the law beyond
> what is reasonable.
>
> There are a lot of things you can't do with bit-fields, but they do
> provide automatically masked and promoted integer arithmetic. On
> balance, though, I'd write the code to use "at least 16 bits" and put
> the masks in myself.

But then, on a machine where C shorts are actually 16-bits, you have to rely
on the compiler to remove the unnecessary masks.

Also, where the intention is to have arrays of such values, then bit-fields
may not work, while simple masking is insufficient, needing shifts and masks
instead, which would be silly where the machines does directly support
16-bits.

--
Bartc

Dann Corbit

unread,
Jun 3, 2010, 9:20:19 AM6/3/10
to
In article <2qmdnQNJioRrFZrR...@bt.com>,
r...@see.sig.invalid says...

>
> bart.c wrote:
> >
> <snip>
>
> > It seems reasonable to be able to request 'a' to be exactly 16-bits on
> > any machine, whether that is natural for the architecture on not.
>
> I'm not entirely convinced that that /is/ a reasonable request. It is
> perfectly reasonable to ask for it to be *at least* 16 bits.
>
> How, precisely, would you implement your exactly-16-bit type on a
> machine whose natural word size is 64?

typedef struct Integer16 { signed value:16; } Integer16 ;

> Such a machine does exist, and C
> implementations for it have to jump through all kinds of crazy hoops to
> give programmers the 8-bit char they expect. I would not like to be the
> one to tell the compiler team "well done lads, but now there's this
> bloke on Usenet who wants 16-bit short ints..."

I think it works everywhere.

Richard Heathfield

unread,
Jun 3, 2010, 9:24:12 AM6/3/10
to
Dann Corbit wrote:
> In article <2qmdnQNJioRrFZrR...@bt.com>,
> r...@see.sig.invalid says...
>> bart.c wrote:
>> <snip>
>>
>>> It seems reasonable to be able to request 'a' to be exactly 16-bits on
>>> any machine, whether that is natural for the architecture on not.
>> I'm not entirely convinced that that /is/ a reasonable request. It is
>> perfectly reasonable to ask for it to be *at least* 16 bits.
>>
>> How, precisely, would you implement your exactly-16-bit type on a
>> machine whose natural word size is 64?
>
> typedef struct Integer16 { signed value:16; } Integer16 ;

That would make even simple addition rather tedious:

Integer16 x = { 6 }; /* braces required */
Integer16 y = { 42 };
Integer16 z;

z.value = x.value + y.value;

Blech!

Dann Corbit

unread,
Jun 3, 2010, 9:26:50 AM6/3/10
to
In article <SDNNn.1596$jL2.533@hurricane>, ba...@freeuk.com says...

Portability may have a cost, in other words. There is no other way that
is fully portable, since the exact width types of C99 are optional.

The O.P.'s goal seems to be some kind of extreme portability. If you
need exact widths, and you need it to work everywhere, then you need bit
fields.

I also doubt that bit fields manipulations will be the bottleneck of any
important operations with the bit fields.

So I think it comes down to these choices:
1. Total portability with bit fields. (Some cost in efficiency and
convenience: arrays, addresses, etc.)
2. Total speed via separate functions for each hardware system (huge
cost in debugging and maintenance)
3. Careful analysis to ensure that the native integral sizes perform
the operations in a satisfactory manner. (huge design effort needed)

I don't know which option is best.

Dann Corbit

unread,
Jun 3, 2010, 9:29:32 AM6/3/10
to
In article <9aadnRACk_1rMZrR...@bt.com>,
r...@see.sig.invalid says...

>
> Dann Corbit wrote:
> > In article <2qmdnQNJioRrFZrR...@bt.com>,
> > r...@see.sig.invalid says...
> >> bart.c wrote:
> >> <snip>
> >>
> >>> It seems reasonable to be able to request 'a' to be exactly 16-bits on
> >>> any machine, whether that is natural for the architecture on not.
> >> I'm not entirely convinced that that /is/ a reasonable request. It is
> >> perfectly reasonable to ask for it to be *at least* 16 bits.
> >>
> >> How, precisely, would you implement your exactly-16-bit type on a
> >> machine whose natural word size is 64?
> >
> > typedef struct Integer16 { signed value:16; } Integer16 ;
>
> That would make even simple addition rather tedious:
>
> Integer16 x = { 6 }; /* braces required */
> Integer16 y = { 42 };
> Integer16 z;
>
> z.value = x.value + y.value;

I didn't say it was pretty.
C++ could tidy up the appearance, but under the covers it would be doing
exactly the same thing.

Willem

unread,
Jun 3, 2010, 12:54:44 PM6/3/10
to
Richard Heathfield wrote:
) Dann Corbit wrote:
)> In article <2qmdnQNJioRrFZrR...@bt.com>,
)> r...@see.sig.invalid says...
)>> How, precisely, would you implement your exactly-16-bit type on a
)>> machine whose natural word size is 64?
)>
)> typedef struct Integer16 { signed value:16; } Integer16 ;
)
) That would make even simple addition rather tedious:
)
) Integer16 x = { 6 }; /* braces required */
) Integer16 y = { 42 };
) Integer16 z;
)
) z.value = x.value + y.value;

How easy would it be to add that syntax to the language ?

Something like:

typedef signed value:16 Integer16;

Or simply
unsigned x:10 = 1000;
unsigned y:10 = 42;
unsigned z:10 = x + y; /* z is now 18 */

I'm not sure but I think that this is a syntax violation in C90/C99,
so it could be added as a feature quite easily, no ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Peter Nilsson

unread,
Jun 3, 2010, 6:36:03 PM6/3/10
to
"bart.c" <ba...@freeuk.com> wrote:
> "Peter Nilsson" <ai...@acay.com.au> wrote in message
> > "Joe" <J...@NoSpammers.Com> wrote:
> > > No reason to have 16-bit signed values suddenly being
> > > stored in 32-bit variables.

Actually there is.

> > Why bother writing 'ANSI C' code if you're going to
> > exclude the plethora of implementations that don't offer
> > precise 16-bit wide integers?
>
> In:
>
> unsigned short a;
> int b=123456;
> a=b;
>
> 'a' may end up as 57920 on some machines, and likely 123456
> on others. It seems reasonable to be able to request 'a' to
> be exactly 16-bits on any machine, whether that is natural
> for the architecture on not.

a = b & 0xFFFFu;

Decent compilers will optimise out the bitwise-and.

More importantly, you can easily and often delay the mask.
Which brings me to the point that even on platforms that
do support 16-bit types, it can actually be _more_ efficient
to perform intermediary calculations with wider _natural_
types.

Twenty years ago, smaller types were faster. That isn't
always true today. In fact, it's the opposite on many
platforms.

--
Peter

bart.c

unread,
Jun 3, 2010, 7:47:20 PM6/3/10
to

"Peter Nilsson" <ai...@acay.com.au> wrote in message
news:bc840f02-f7f3-4bfd...@y18g2000prn.googlegroups.com...

> "bart.c" <ba...@freeuk.com> wrote:
>> "Peter Nilsson" <ai...@acay.com.au> wrote in message
>> > "Joe" <J...@NoSpammers.Com> wrote:
>> > > No reason to have 16-bit signed values suddenly being
>> > > stored in 32-bit variables.
>
> Actually there is.

>> unsigned short a;


>> int b=123456;
>> a=b;
>>
>> 'a' may end up as 57920 on some machines, and likely 123456
>> on others.

> a = b & 0xFFFFu;


>
> Decent compilers will optimise out the bitwise-and.
>
> More importantly, you can easily and often delay the mask.
> Which brings me to the point that even on platforms that
> do support 16-bit types, it can actually be _more_ efficient
> to perform intermediary calculations with wider _natural_
> types.

Another example:

unsigned short a,b;

b=0xffff;
a=(b<<1)>>1;

'a' has a result that depends on whether the intermediate calculations are
done with the same number of bits as short, or more, resulting in subtle
differences between implementations.

Masks can fix this too, but now it starts to get untidy.

But this is a consequence of the way C works; one of my old language
projects does this properly and gives the expected result for 'a' (ie.
0x7fff when using 16-bits).

> Twenty years ago, smaller types were faster. That isn't
> always true today. In fact, it's the opposite on many
> platforms.

Whether smaller types are always slower is debatable; you need to look at
memory accesses too.

(Otherwise, yes my newer projects use 32-bit calculations; shorter types are
mainly there to save space; any extra speed is a bonus. However I now also
have the same problem as C has above; my excuse is that my 16-bit type is
not an proper type, only a narrow version of 32-bits...)

--
Bartc

Peter Nilsson

unread,
Jun 7, 2010, 11:00:17 PM6/7/10
to
"bart.c" <ba...@freeuk.com> wrote:
> "Peter Nilsson" <ai...@acay.com.au> wrote:

> > "bart.c" <ba...@freeuk.com> wrote:
> > > unsigned short a;
> > > int b=123456;
> > > a=b;
> > >
> > > 'a' may end up as 57920 on some machines, and likely 123456
> > > on others.
> >
> >  a = b & 0xFFFFu;
> >
> > Decent compilers will optimise out the bitwise-and.
>
> Another example:
>
> unsigned short a,b;
>
> b=0xffff;
> a=(b<<1)>>1;
>
> 'a' has a result that depends on whether the intermediate
> calculations are done with the same number of bits as short,
> or more, resulting in subtle differences between
> implementations.

That's because you've coded it that way.

> Masks can fix this too, but now it starts to get untidy.

What is 'untidy' about...?

a = b & 0x7FFFu;

--
Peter

bart.c

unread,
Jun 8, 2010, 5:49:44 AM6/8/10
to

It was supposed to be an example of the widths of intermediate values being
significant. Try this then:

a=(b<<c)>>c;

Or any calculation where high-order bits can affect the result (>>, / and %
for example).

--
Bartc

0 new messages