Standard integer types vs <stdint.h> types

B

Bart C

Malcolm McLean said:
A struct is a hard-coded associative array. So rather a special beast.
Normally we wouldn't think of it as one of the basic data structures
(stack, queue, linked list, tree, graph and so on) at all.

What are all these except a bunch of structs linked with pointers? Granted
they have to be assembled manually.

Which (non-esoteric) languages have these built-in /to the language/ rather
than in the library?

Bart
 
B

Bart C

James Kuyper said:
No, you use conditional compilation of typedefs, of course.

Ok, like this then?

#include <limits.h>
#if INT_MAX>=2147483647
typedef int myint32;
#elif LONG_MAX>=2147483647
typedef long int myint32;
#else
typedef long long int myint32;
#endif

myint32 a=2000000000;

(Although I can see a few pitfalls like having a possible varying suffix to
int constants, and varying printf format specifier, depending on which int
is chosen.)
 
J

James Kuyper

Harald van Dijk wrote:
....
I was assuming the code would not be compiled from any of the standard
include locations. When it's not, <stdint.h> first searches the standard
include locations, never seeing the custom stdint.h. C90 implementations
without <stdint.h> would search the standard include locations first,
fail to find anything, and then behave as if #include "stdint.h" was used.

The behaviour is not meant to be undefined if a file named stdint.h is
placed in a location searched for #include "..." but not #include <...>,
is it? "Standard places" isn't completely clear, so I'm not entirely sure.

It's very deliberately vague; the standard says very little about these
issues. There's an implementation-defined list of locations which are
searched when you use #include <filename>, and a possibly, but not
necessarily, different implementation-defined list of locations that are
searched when you use #include "filename". About the only relevant thing
the standard says is that if the set of places searched by

#include "filename"

doesn't contain the named file, the search is repeated as

if #include <filename>

had been written.

If you use a compiler in a mode where it supports at least <stdint.h>
(even if it doesn't support any other C99 feature), you need to make
sure that no user-defined file of that name is in the list of standard
search locations. You'll need to read your implementation's
documentation to determine which places those are, and there's no
guarantee that they doesn't include the current directory or the
directory containing the source code file that has the #include line in
it. There's no guarantee about the order that they're searched in, and
there's no guarantee that later finds in the search order will be
ignored. In practice, the implementation itself often provides such
guarantees, but there's no such requirement in the standard.
 
J

James Kuyper

Bart said:
Ok, like this then?

#include <limits.h>
#if INT_MAX>=2147483647
typedef int myint32;
#elif LONG_MAX>=2147483647
typedef long int myint32;
#else
typedef long long int myint32;
#endif

myint32 a=2000000000;

Yes, that's the idea.
(Although I can see a few pitfalls like having a possible varying suffix to
int constants, and varying printf format specifier, depending on which int
is chosen.)

You can also conditionally compile code which #defines macros for
attaching the appropriate suffix, if necessary, and for the appropriate
printf format specifier, exactly as is done in typical implementations
of <stdint.h>. That is precisely what the publicly available
C90-compatible portable versions of stdint.h do. That's why using
<stdint.h> is a better way to do this, even if you have to use one of
the C90 versions when compiling in C90 (and make sure it is NOT used
when compiling in C99).
 
J

Jean-Marc Bourguet

Malcolm McLean said:
Lisp is structured around linked lists.

Lisp is structured around binary trees and consider linked lists as a
special case of binary trees.

Yours,
 
H

Harald van Dijk

If you use a compiler in a mode where it supports at least <stdint.h>
(even if it doesn't support any other C99 feature), you need to make
sure that no user-defined file of that name is in the list of standard
search locations. You'll need to read your implementation's
documentation to determine which places those are, and there's no
guarantee that they doesn't include the current directory or the
directory containing the source code file that has the #include line in
it.

You're right, that's possible, and I didn't think of that. I would
normally consider that pretty poor quality, but there are probably even
implementations where it's the most sensible decision (if directories are
not available at all, perhaps).
 
B

Ben Bacarisse

CBFalconer said:
Notice the word 'basic'. structs could be called compound objects.

Malcolm had stated that arrays are the only "basic data structures"
(with support in the language). They too could be called compound.
 
M

Malcolm McLean

Ben Bacarisse said:
Malcolm had stated that arrays are the only "basic data structures"
(with support in the language). They too could be called compound.
In chemistry we'd call structs "compounds" and arrays "polymers".
 
A

Army1987

Malcolm said:
That's a totally untypical program. Most C programs use arrays very heavily.
In fact it is the only basic data structure that has direct language
support.
Sometimes in older C programs you see pointer notation used where array
dereferencing would be clearer, I'll grant you. That's technically an
exception to my point, even though an integer will be used to count down the
travelling pointer.

I can't see any reason why a program using:
for (p = a; p < a + n; p++) {
frobnicate(*a);
}
is any more "untypical" or less "clear" than
for (i = 0; i < n; i++) {
frobnicate(a);
}
 
A

Army1987

dj3vande said:
In a mathematical context, it's quite common to hear mathematicians
making claims like "the reals are a superset of the rationals".

Except they're not; the rationals are equivalence classes over ordered
pairs of integers, and the reals are sets of rationals[1], so no
rational number can possibly be a real number. This doesn't keep it
from being understood as "the rationals are isomorphic to a subset of
the reals", for both the person making the claim and the person hearing
it.
[1] Sometimes. There are several equivalent constructions, but these
are the ones that I saw in my math courses.
But, as far as I know, it's impossible to construct the reals in a
way that makes them look the same as the rationals, which is my
point here.

Take the set of real numbers, remove the ones in the subset isomorphic to
Q, and replace them with the true Q.
(You can perform this before, with the rationals, too: define Q to be the
union of Z and the set of equivalence classes on {(x,y) in ZxZ: y !=0 and x
% y != 0 }. )

(This construction only serves to make one more comfortable in thinking
that R c Q c Z, but it's otherwise not useful to anything.)
 
M

Malcolm McLean

Army1987 said:
Malcolm said:
That's a totally untypical program. Most C programs use arrays very
heavily.
In fact it is the only basic data structure that has direct language
support.
Sometimes in older C programs you see pointer notation used where array
dereferencing would be clearer, I'll grant you. That's technically an
exception to my point, even though an integer will be used to count down
the
travelling pointer.

I can't see any reason why a program using:
for (p = a; p < a + n; p++) {
frobnicate(*a);
}
is any more "untypical" or less "clear" than
for (i = 0; i < n; i++) {
frobnicate(a);
}

You've answered your own question.
Example 1 is incorrect.
 
R

Richard Tobin

I can't see any reason why a program using:
for (p = a; p < a + n; p++) {
frobnicate(*a);
}
is any more "untypical" or less "clear" than
for (i = 0; i < n; i++) {
frobnicate(a);
}
[/QUOTE]
You've answered your own question.
Example 1 is incorrect.

I don't think a typo in an example proves much. He could have typed,
say, a[n] in the second case and it would have been just as wrong.

-- Richard
 
P

Paul Hsieh

What are all these except a bunch of structs linked with pointers?

Methods maybe? For example, the call *stack* in C is not a C struct
with a set of pointers. Heap sort is also performed on a tree
structure called a heap -- except its almost always implemented in an
array.
Granted they have to be assembled manually.

I think that's what Malcolm's original point was. Structs, pointers
and arrays are really just the building blocks for real data
structures.

Unfortunately, a single flat record sequence (i.e., a struct) is also
a data structure, so I don't think his distinction is precise enough.
 
M

Malcolm McLean

Paul Hsieh said:
I think that's what Malcolm's original point was. Structs, pointers
and arrays are really just the building blocks for real data
structures.

Unfortunately, a single flat record sequence (i.e., a struct) is also
a data structure, so I don't think his distinction is precise enough.
You could argue it is. A floating point number is also a "data structure" on
that definition, since it has a flag, an exponent, and a mantissa.

In general terms, by "data structure" we don't mean "a type of struct". We
means "several similar items linked together in some way".
 
K

Keith Thompson

Bart C said:
Ok, like this then?

#include <limits.h>
#if INT_MAX>=2147483647
typedef int myint32;
#elif LONG_MAX>=2147483647
typedef long int myint32;
#else
typedef long long int myint32;
#endif

myint32 a=2000000000;

Note that LONG_MAX is guaranteed to be at least 2147483647; if the
final #else is triggered, it tells you that the implementation is
broken.
(Although I can see a few pitfalls like having a possible varying suffix to
int constants, and varying printf format specifier, depending on which int
is chosen.)

Ths suffix is needed in some, but not all, contexts. For your
declaration ``myint32 a=2000000000;'', it's not needed, because the
literal will automatically be of the appropriate type. But if you had
written it as
myint32 a = 2000 * 1000 * 1000;
the initialization would be of type int, and could overflow. You
could define a macro to token-paste the appropriate suffix, or you
could use a cast:
myint32 a = (myint32)2000 * 1000 * 1000;

As for printf formats, C99's <inttypes.h> defines macros for those,
but IMHO they're ugly. For the *printf functions, you can convert the
operands to the longest available integer type of the appropriate
signedness (long in C90, intmax_t in C99, or you can define your own);
for *scanf, you can store in a wide temporary and then assign to the
object of the type you want.
 
A

Army1987

jacob said:
I mean if I have some data (like 45 000) how the hell I am supposed to
know if the implementation supports that unless I use can hold that?

I cannot parse the second half of the sentence, but what's wrong with
`long n = 45000; ` or `unsigned n = 45000; `?
 
F

Flash Gordon

Malcolm McLean wrote, On 24/01/08 13:12:
You could argue it is. A floating point number is also a "data
structure" on that definition, since it has a flag, an exponent, and a
mantissa.

As I pointed out else-thread some lecture notes refer to integer types
as basic data structures.
In general terms, by "data structure" we don't mean "a type of struct".
We means "several similar items linked together in some way".

A data structure can link a number of dissimilar items together in some
way. If you want an example that is more complex than a C struct then
look at relational databases, specifically joins.

In any case, as there is more than one possible definition of what
qualifies as a "basic data structure" you cannot say what support C has
for them unless you first define what you mean by "basic data structure".
 
C

Chris Hills

Malcolm McLean said:
My own view is that you should be able to stick to char for characters
and int for integers, in almost every situation. However this is only
tenable if you can use int as both an arbitrary array index and a fast
type.

Signed and unsigned char are integer types.
Plain char is a character type (and the signed/unsigned is
implementation dependant)

there are more 8 bit MCU out there than anything else. They usually use
signed/unsigned char as their base type for most things.
 
C

Chris Hills

For exact-width types, I actually lean toward considering ugliness a
Good Thing.

Most people who think they need exact-width types are wrong, and making
them as ugly and inconvenient as possible discourages their use (which
on the whole is a Good Thing); but when you actually do need them (I've

On embedded systems when you interface to hardware, do bit manipulation
etc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

C99 integer types 24
Types 58
Types in C 117
Integer types in embedded systems 22
C99 stdint.h 20
Performance of signed vs unsigned types 84
ansi types 11
using pre-processor to count bits in integer types... 17

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top