4

I am studying how the C language works. I can find definitions for types like int8_t, intptr_t, etc in <stdlib.h>:

// Represents true-or-false values
typedef _Bool bool;
enum { false, true };

// Explicitly-sized versions of integer types
typedef __signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;

// Pointers and addresses are 32 bits long.
// We use pointer types to represent virtual addresses,
// uintptr_t to represent the numerical values of virtual addresses,
// and physaddr_t to represent physical addresses.
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
typedef uint32_t physaddr_t;

However, I can't find the definition of type like char . Thus my question is, where are int and char defined?

4 Answers4

8

In which header file is char defined?

Nowhere - char is a builtin type, not a user-defined one. It's part of the core language. The same applies to int.

Is there no definition at all of these builtin types?

There is. The standard does defines these builtin types.


Note that both char and int are also keywords, which means you can't use them as identifiers, because they have a reserved and already assigned use in the language.

JFMR
  • 23,265
  • 4
  • 52
  • 76
  • 1
    `Nowhere`. How then does the compiler designer know what to implement. Is it left for their discretion? (for example `char` to be 32 bit float number and `double` to be two byte character?) – 0___________ Aug 11 '17 at 14:26
  • Thanks a lot! But I am still curious about what does it mean to be `builtin`? I mean it must be defined somewhere right? Not necessary in C. I know this might sounds silly. I will appreciate it if you can give me some hint. – Christy Lee Aug 11 '17 at 14:27
  • They're defined in the standard. They can't be defined anywhere else because how can you define a type without any existing types or a custom type declaration statement (size, padding bits, signness, alignment...) built into the standard? – phuclv Aug 13 '17 at 11:22
  • @ChristyLee: The compiler decides how many bytes long an `int` is. When it sees C code that declares an `int`, it allocates that much memory for that variable. – luther Aug 13 '17 at 17:45
5

The char and int types, among others, are not defined in any header file. They are built in types, meaning they are part of the core language. Their definitions are hardcoded into the compiler itself.

As to how the compiler defines what those types are, that is dictated by the C standard.

The definition of int and char can be found in section 6.2.5 (Types). For example, the definition of char:

3 An object declared as type char is large enough to store any member of the basic execution character set. If a member of the basic execution character set is stored in a char object, its value is guaranteed to be nonnegative. If any other character is stored in a char object, the resulting value is implementation-defined but shall be within the range of values that can be represented in that type.

Definitions for the other types, as well as the minimum range of values for each type, follow.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    The C standard specifies minimum requirements of the basic types. It does not dictate all requirements, and a compiler is permitted to exceed the minimum requirements. For example, an `int` is REQUIRED to be able to represent the range of values `-32767` to `32767`, but a lot of compilers provide an `int` that can represent a larger range (e.g. a 32-bit type). – Peter Aug 11 '17 at 14:51
1

Thus, here is my question, where is int, char defined?

They are defined here: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

Page 57+ in reader or 39+ in the document

0___________
  • 60,014
  • 4
  • 34
  • 74
  • @KevinDTimm I know - it is difficult to find chapter : "Types" as its title is extremely confusing – 0___________ Aug 11 '17 at 14:43
  • The official ratified version are available at ansi and ISO web pages (for a fee), not on open-std.org (or isocpp.org). The versions on open-std.org are not officially ratified (e.g. are drafts that precede the officially released standards, even if deltas from the official standard are pretty minor in the late drafts). – Peter Aug 11 '17 at 14:57
  • @KevinDTimm What for? many pages. Everyone reading this can open the document :) – 0___________ Aug 11 '17 at 15:00
  • @Peter are you going to be a sponsor? – 0___________ Aug 11 '17 at 15:01
  • @PeterJ Sponsor? – Peter Aug 11 '17 at 15:11
  • @Peter if you advice people to buy 200 bucks+ document - maybe you should open the fund especially for students and sponsor this document. – 0___________ Aug 11 '17 at 15:16
  • Read the SO suggestions / to paraphrase / include the information and not just a link as links go away. – KevinDTimm Aug 11 '17 at 20:00
  • @PeterJ - I am not advising people to buy a document. I simply pointed out which is the ratified source and which is an informal alternative. Your wording portrayed your link as being to a definitive source, which it is not - and therefore misleading in context of the question asked. People can decide for themselves which version meets their needs. – Peter Aug 11 '17 at 22:14
  • @Peter - do you think that we are so stupid, and we do know that the document we use is a draft? And there is a not free official non draft one? Thank you for such a judgement. – 0___________ Aug 11 '17 at 22:16
  • @PeterJ - Not everyone knows that - and I don't consider ignorance to be stupidity. The OPs question demonstrated no understanding of the place of the standard in defining the language, let alone awareness of different versions or sources. – Peter Aug 11 '17 at 22:23
1

Note that those "definitions" of int8_t, intptr_t, etc., are simply aliases for built-in types.

The basic data types char, int, long, double, etc., are all defined internally to the compiler - they're not defined in any header file. Their minimum ranges are specified in the language standard (a non-official, pre-publication draft is available here).

The header file <limits.h> will show the ranges for different integer types for the particular implemention; here's an excerpt from the implementation I'm using:

/* Number of bits in a `char'.  */
#  define CHAR_BIT      8

/* Minimum and maximum values a `signed char' can hold.  */
#  define SCHAR_MIN     (-128)
#  define SCHAR_MAX     127

/* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */
#  define UCHAR_MAX     255

/* Minimum and maximum values a `char' can hold.  */
#  ifdef __CHAR_UNSIGNED__
#   define CHAR_MIN     0
#   define CHAR_MAX     UCHAR_MAX
#  else
#   define CHAR_MIN     SCHAR_MIN
#   define CHAR_MAX     SCHAR_MAX
#  endif

/* Minimum and maximum values a `signed short int' can hold.  */
#  define SHRT_MIN      (-32768)
#  define SHRT_MAX      32767

/* Maximum value an `unsigned short int' can hold.  (Minimum is 0.)  */
#  define USHRT_MAX     65535

/* Minimum and maximum values a `signed int' can hold.  */
#  define INT_MIN       (-INT_MAX - 1)
#  define INT_MAX       2147483647

/* Maximum value an `unsigned int' can hold.  (Minimum is 0.)  */
#  define UINT_MAX      4294967295U

/* Minimum and maximum values a `signed long int' can hold.  */
#  if __WORDSIZE == 64
#   define LONG_MAX     9223372036854775807L
#  else
#   define LONG_MAX     2147483647L
#  endif

Again, this doesn't define the types for the compiler, this is just informational; you can use these macros to guard against overflow, for example. There's a <float.h> header that does something similar for floating-point types.

The char type must be able to represent at least every value in the basic execution character set - upper and lower case Latin alphabet, all decimal digits, common punctuation characters, and control characters (newline, form feed, carriage return, tab, etc.). char must be at least 8 bits wide, but may be wider on some systems. There's some weirdness regarding the signedness of char - the members of the basic execution character set are guaranteed to be non-negative ([0...127]), but additional characters may have positive or negative values, so "plain" char may have the same range as either signed char or unsigned char. It depends on the implementation.

The int type must be able to represent values in at least the range [-32767...32767]. The exact range is left up to the implementation, depending on word size and signed integer representation.

C is a product of the early 1970s, and at the time there was a lot of variety in byte and word sizes - historically, bytes could be anywhere from 7 to 9 bits wide, words could be 16 to 18 bits wide, etc. Powers of two are convenient, but not magical. Similarly, there are multiple representations for signed integers (2's complement, 1's complement, sign magnitude, etc.). So the language definition specifies the minimum requirements, and it's up to the implementor to map those onto the target platform.

John Bode
  • 119,563
  • 19
  • 122
  • 198