What is the reasoning behind types to be redefined in GLib? Why do they turn char into gchar, int into gint, etc.?
Check out Basic Types in the GLib documentation. Essentially, it's to guarantee that certain types will exist with certain semantics, regardless of which C compiler or platform you're using. The types that C guarantees anyway are typedefed just to make all of the type names look uniform.
See also this answer.
Essentially, it's because glib's standard-width types such as guint32 predate the C99 and later standard-width types, such as uint32_t, which now exists (as of C99 and later) and is exactly equivalent.
So, glib's g-prefixed types are now essentially obsolete. Use the standardized fixed-width types like uint32_t now instead.
Related
here is a small (and working) C code:
typedef __builtin_va_list __va_list;
int main() {
return 0;
}
I found an answer, how gcc found the base type:
Pycparser not working on preprocessed code
But how can I list all of the __builtin_ "base" types, which not defined explicitly?
Thanks,
a.
how can I list all of the __builtin_ "base" types, which not defined explicitly?
TL;DR: there is no general-purpose way to do it.
The standard does not define any such types, so they can only be implementation-specific. In particular, C does not attribute any significance to the __builtin_ name prefix (though such identifiers are reserved), nor does it acknowledge that any types exist that are not derived from those it does define. Thus, for most purposes, the types you are asking about should be considered an implementation detail.
If there were a way to list implementation-specific built-in types, it would necessarily be implementation-specific itself. For example, you might be able to find a list such as you are after in the compiler's documentation. You could surely derive one from the compiler's own source code, if that's available to you. You could maybe extract strings from the compiler binary, and filter for a characteristic name pattern, such as strings starting with "__builtin_".
You could also consider parsing all the standard library headers (with the assumption that they are correct) to find undeclared types, though that's not guaranteed to find all the available types. Moreover, with some systems, for example GNU's, the C standard library (to which the headers belong) is separate from the compiler.
Basic question: is there a portable (or at least, a library that is found in most compilers) way to query the type of a void* pointer at runtime? In particular, is it possible to determine if the pointer is of type struct x or of type struct y (as an example).
Additional info: I know gcc offers the typeof operator, but I want a more portable, less compiler-dependent way of accomplishing the same thing.
Requirements:
Must not be completely compiler-dependent. This includes compiler-specific macros and other features not commonly implemented in most compilers.
I would prefer a function that works on any compiler over any less portable implementation (though I will accept the answer that best suits my goals).
It is okay to suggest using a function in a library that is not in the C11 function, but is commonly found in most compilers. Make sure you explain how it works and the arguments though.
What you're asking for is impossible. A void * pointer is by definition a generic pointer. It can be cast to or from a pointer of any type; there is no way to determine what type of data (if any!) it points to.
Just curious if u_char is a standard. I've always used it assuming it was defined along with uintX_t types and so on. But am seeing some of our code base transition from u_char to "unsigned char" with a reason "so users don't have to define u_char themselves"..
The string u_char does not appear in this draft of the C standard:
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
It's not required by POSIX either, as far as I know.
I think it's in BSD (sys/types.h), and Windows (winsock.h). I would not consider either one to be "a standard" - they aren't formal standards, and they certainly aren't part of standard C, but they are clearly defined and documented.
No, u_char is non-standard. If you need to use a standard type that's equivalent to u_char, you can use uint8_t which is part of the C99 standard library (check your specific platforms/compilers for C99-compliance). stdint.h defines this type (along with many other specific integral types). This Wikipedia article contains more information about stdint.h.
It's not present in any older header files (except certain specific areas, like Kerberos and networking headers), and not a built-in type in any compiler I know of.
sizeof is a C keyword. It returns the size in a type named size_t. However, size_t is not a keyword, but is defined primarily in stddef.h and probably other C standard header files too.
Consider a scenario where you want to create a C program which does not include any C standard headers or libraries. (Like for example, if you are creating an OS kernel.) Now, in such code, sizeof can be used (it is a C keyword, so it is a part of the language), but the type that it returns (size_t) is not available!
Does not this signify some kind of a problem in the C standard specification? Can you clarify this?
It does not literally return a value of type size_t since size_t is not a concrete type in itself, but rather a typedef to an unspecified built-in type. Typedef identifiers (such as size_t) are completely equivalent to their respective underlying types (and are converted thereto at compile time). If size_t is defined as an unsigned int on your platform, then sizeof returns an unsigned int when it is compiled on your system. size_t is just a handy way of maintaining portability and only needs to be included in stddef.h if you are using it explicitly by name.
sizeof is a keyword because, despite it's name and usage, it is an operator like + or = or < rather than a function like printf() or atoi() or fgets(). A lot of people forget (or just don't know) that sizeof is actually an operator, and is always resolved at compile-time rather than at runtime.
The C language doesn't need size_t to be a usable, consistent language. That's just part of the standard library. The C language needs all operators. If, instead of +, C used the keyword plus to add numbers, you would make it an operator.
Besides, I do semi-implicit recasting of size_ts to unsigned ints (and regular ints, but Kernighan and Ritchie will someday smite me for this) all the time. You can assign the return type of a sizeof to an int if you like, but in my work I'm usually just passing it straight on to a malloc() or something.
Some headers from the C standard are defined for a freestanding environment, i.e. fit for use e.g. in an operating system kernel. They do not define any functions, merely defines and typedefs.
They are float.h, iso646.h, limits.h, stdarg.h, stdbool.h, stddef.h and stdint.h.
When working on an operating system, it isn't a bad idea to start with these headers. Having them available makes many things easier in your kernel. Especially stdint.h will become handy (uint32_t et al.).
Does not this signify some kind of a problem in the C standard specification?
Look up the difference between a hosted implementation of C and a freestanding C implementation. The freestanding (C99) implementation is required to provide headers:
<float.h>
<iso646.h>
<limits.h>
<stdarg.h>
<stdbool.h>
<stddef.h>
<stdint.h>
These headers do not define any functions at all. They define parts of the language that are somewhat compiler specific (for example, the offsetof macro in <stddef.h>, and the variable argument list macros and types in <stdarg.h>), but they can be handled without actually being built into the language as full keywords.
This means that even in your hypothetical kernel, you should expect the C compiler to provide these headers and any underlying support functions - even though you provide everything else.
I think that the main reasons that size_t is not a keyword are:
there's no compelling reason for it to be. The designers of the C and C++ languages have always preferred to have language features be implemented in the library if possible and reasonable
adding keywords to a language can create problems for an existing body of legacy code. This is another reason they are generally resistant to adding new keywords.
For example, in discussing the next major revision of the C++ standard, Stroustrup had this to say:
The C++0x improvements should be done in such a way that the resulting language is easier to learn and use. Among the rules of thumb for the committee are:
...
Prefer standard library facilities to language extensions
...
There is no reason not to include stddef.h, even if you are working on a kernel - it defines type sizes for your specific compiler that any code will need.
Note also that almost all C compilers are self-compiled. The actual compiler code for the sizeof operator will therefore use size_t and reference the same stddef.h file as does user code.
From MSDN:
When the sizeof operator is applied
to an object of type char, it yields 1
Even if you don't have stddef.h available/included and don't know about size_t, using sizeof you can get the size of objects relative to char.
size_t is actually a type - often an unsigned int. Sizeof is an operator that gives the size of a type. The type returned by sizeof is actually implementation-specific, not a C standard. It's just an integer.
Edit:
To be very clear, you do not need the size_t type in order to use sizeof. I think the answer you're looking for is - Yes, it is inconsistent. However, it doesn't matter. You can still practically use sizeof correctly without having a size_t definition from a header file.
size_t is not a keyword by necessity. Different architectures often have different sizes for integral types. For example a 64 bit machine is likely to have an unsigned long long as size_t if they didn't decide to make int a 64 bit datatype.
If you make sizeof a builtin type to the compiler, then it will take away the power to do cross compilation.
Also, sizeof is more like a magic compile time macro (think c++ template) which explains why it is a keyword instead of defined type.
The simple reason is because it is not a fundamental type. If you look up the C standard you will find that fundamental types include int, char etc but not size_t. Why so? As others have already pointed out, size_t is an implementation specific type (i.e. a type capable of holding the size in number of "C bytes" of any object).
On the other hand, sizeof is an (unary) operator. All operators are keywords.
This seems like a simple question, but I can't find it with the Stack Overflow search or Google. What does a type followed by a _t mean? Such as
int_t anInt;
I see it a lot in C code meant to deal closely with hardware—I can't help but think that they're related.
As Douglas Mayle noted, it basically denotes a type name. Consequently, you would be ill-advised to end variable or function names with '_t' since it could cause some confusion. As well as size_t, the C89 standard defines wchar_t, off_t, ptrdiff_t, and probably some others I've forgotten. The C99 standard defines a lot of extra types, such as uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t, and so on. These new types are formally defined in <stdint.h> but most often you will use <inttypes.h> which (unusually for standard C headers) includes <stdint.h>. It (<inttypes.h>) also defines macros for use with the printf() and scanf().
As Matt Curtis noted, there is no significance to the compiler in the suffix; it is a human-oriented convention.
However, you should also note that POSIX defines a lot of extra type names ending in '_t', and reserves the suffix for the implementation. That means that if you are working on POSIX-related systems, defining your own type names with the convention is ill-advised. The system I work on has done it (for more than 20 years); we regularly get tripped up by systems defining types with the same name as we define.
The _t usually wraps an opaque type definition.
GCC merely add names that end with _t to the reserved namespace you may not use, to avoid conflicts with future versions of Standard C and POSIX (GNU C library manual). After some research, I finally found the correct reference inside the POSIX Standard 1003.1: B.2.12 Data Types (Volume: Rationale, Appendix: B. Rationale for System Interfaces, Chapter: B.2 General Information):
B.2.12 Data Types
Defined Types
The requirement that additional types defined in this section end in "_t" was prompted by the problem of name space pollution. It is difficult to define a type (where that type is not one defined by POSIX.1-2017) in one header file and use it in another without adding symbols to the name space of the program. To allow implementors to provide their own types, all conforming applications are required to avoid symbols ending in "_t", which permits the implementor to provide additional types. Because a major use of types is in the definition of structure members, which can (and in many cases must) be added to the structures defined in POSIX.1-2017, the need for additional types is compelling.
In a nutshell, the Standard says that there are good chances of extending the Standard types' list, therefore the Standard restricts the _t namespace for its own use.
For instance, your program matches POSIX 1003.1 Issue 7 and you defined a type foo_t. POSIX 1003.1 Issue 8 is eventually released with a newly defined type foo_t. Your program does not match the new version, which might be a problem. Restricting the _t usage prevents from refactoring the code. Thus, if you aim to a POSIX compliancy, you should definitely avoid the _t as the Standard states it.
Side note: personally, I try to stick to POSIX because I think it gives good basics for clean programming. Moreover, I am pretty fond of Linux Coding Style (chapter 5) guidelines. There are some good reasons why not using typedef. Hope this help!
It's a convention used for naming data types, e.g with typedef:
typedef struct {
char* model;
int year;
...
} car_t;
It is a standard naming convention for data types, usually defined by typedefs. A lot of C code that deals with hardware registers uses C99-defined standard names for signed and unsigned fixed-size data types. As a convention, these names are in a standard header file (stdint.h), and end with _t.
The _t does not inherently have any special meaning. But it has fallen into common use to add the _t suffix to typedef's.
You may be more familiar with common C practices for variable naming... This is similar to how it's common to stick a p at the front for a pointer, and to use an underscore in front of global variables (this is a bit less common), and to use the variable names i, j, and k for temporary loop variables.
In code where word-size and ordering is important, it's very common to use custom defined types that are explicit, such as BYTE WORD (normally 16-bit) DWORD (32-bits).
int_t is not so good, because the definition of int varies between platforms -- so whose int are you conforming to? (Although, these days, most PC-centric development treats it as 32 bits, much stuff for non-PC development still treat int's as 16 bits).
It's just a convention which means "type". It means nothing special to the compiler.
It means type. size_t is the size type.
There were a few good explanations about the subject. Just to add another reason for re-defining the types:
In many embedded projects, all types are redefined to correctly state the given sizing to the types and to improve portability across different platforms (i.e hardware types compilers).
Another reason will be to make your code portable across different OSs and to avoid collisions with existing types in the OS that you are integrating in your code. For this, usually a unique (as possible) prefix is added.
Example:
typedef unsigned long dc_uint32_t;
If you're dealing with hardware interface code, the author of the code you're looking at might have defined int_t to be a specific size integer. The C standard doesn't assign a specific size to the int type (it depends on your compiler and target platform, potentially), and using a specific int_t type would avoid that portability problem.
This is a particularly important consideration for hardware interface code, which may be why you've first noticed the convention there.
For example in C99, /usr/include/stdint.h:
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
#ifndef __uint32_t_defined
typedef unsigned int uint32_t;
# define __uint32_t_defined
#endif
#if __WORDSIZE == 64
typedef unsigned long int uint64_t;
#else
__extension__
typedef unsigned long long int uint64_t;
#endif
_t always means defined by typedef.