In 2011 a new version of the C standard, C11, was released. And
gcc has implemented most of the changes from C11.
As h2bi translates C header files to fb header files the new
standard could have an impact on h2bi. I've looked at the
new standard to see whether it contains things h2bi should be
able to deal with.
C11 added some new keywords which should get incorporated into
h2bi.
First up is a new storage class specifier (used like you'd use static, extern, register or auto).
_Thread_local_Thread_local is just here so you know it's out there. According to the standard _Thread_local
cannot be used in the declaration specifiers of a function declaration.
Which means h2bi only has to deal with _Thread_local as it appears in combination with variables
declared as extern or static. Translating _Thread_local is not possible (no fb equivalent)
and dropping it during translation is the right course of action. _Thread_local is more of
a hint to the C compiler than anything else (not something h2bi should be too concerned with).
The following are two new type qualifiers
(used like you'd use const or volatile)
restrict According to the C11 standard restrict can be dropped from source
code without impacting the correct functioning of a program.
Hence h2bi can simply drop restrict from C declarations (eg drop
restrict during translation).
Restrict is the one keyword I think will pop up in the wild
soon. It's related to pointer aliasing (code optimization) and
because a compiler can simply ignore it and still be standard compliant
I can see how restrict could see some use from C programmers.
Standard header files found in the standard already use the restrict
keyword which is telling (I think).
Moving on to the next keyword.
_Atomic_Atomic should be recognized by h2bi. And subsequently dropped.
There is no fb equivalent for _Atomic and _Atomic is more of a hint
for the C compiler on how to deal with a variable. An example.
a returns an integer with an _Atomic qualifer. But an int is an int is an int
regardless of the addition of the qualifier _Atomic.
That's it as far as qualifiers are concerned. Next is a new type specifier.
(used like you'd use be int, void, struct etc...)
_Atomic(type-name)Yes, that's the same keyword used in a different context. If _Atomic is immediately
followed by ( it's a type specifier. Otherwise it's a type qualifier.
Confusing, isn't it? Same deal as using _Atomic as a type qualifier with one difference.
According to the C standard a declaration HAS to contain a type-specifier.
_Atomic used as a qualifier can be dropped as it only adds something to a type-specifier.
The type-specifier cannot be dropped as that will render the declaration useless.
So dropping _Atomic(type-name) completely is not an option.
_Atom(type-name) could be translated as if it read type-name. And then h2bi can translate
type-name in the usual manner.
An example to clarify.
The size of an _Atomic(int) can differ from the size of an ordinary int. It can but it
doesn't (at least it doesn't in gcc).
_Atomic (along with most of the other changes) have been added to the C standard to keep
up with the C++ standard. C++11 and C11 are kept in-sync with regards to certain parts of
the syntax.
Enough about _Atomic. Onward to a function specifier (used like you'd use inline)
_NoreturnFunctions declared inline do not necessarily turn up in the binaries of a library.
As h2bi creates header files that are going to be used with binaries
inline functions are of little interest to h2bi..
_Noreturn is a different story. _Noreturn means 'there is
no return statement in this function'. The function therefore will not
return to it's caller. Functions like abort() are functions that do not return.
Like restrict it's more of a hint for the compiler so it knows a function does not return.
A compiler could use this information to optimize a call to a function with a _Noreturn
function specifier.
A function declared using _Noreturn should be declared as void. h2bi would translate such
a function as a sub. Dropping _Noreturn seems like the right way to deal with _Noreturn.
Aside: C11 adds a standard header file for using _Atomic called <stdatomic.h>. Other
header files added to the standard library are <stdalign.h>, <stdnoreturn.h>, <threads.h>
and <uchar.h>. Most of these standard header files contain a macro that expands to a keyword.
For example <stdnoreturn.h> has a macro, noreturn, that expands to _Noreturn.
Same for thread_local in <threads.h> (expands to _Thread_local) and alignas in <stdalign.h>
(expands to _Alignas).
It could be an idea to watch out for inclusion of these standard header files so h2bi
knows that noreturn is actually _Noreturn,
Moving on to some nastiness: a complete new type of specifier called the alignment-specifier.
_Alignas(type-name)
_Alignas(constant-expression)
_Alignas cannot be used in a function declaration. And it can't be used within the context
of a typedef. Which limits it's impact on h2bi somewhat.
An example of _Alignas.
Code: Select all
// every object of type sse_t will be aligned to 16-byte boundary
struct alignas(16) sse_t
{
float sse_data[4];
};
I am guessing that h2bi will not have to translate _Alignas due to the typedef and
function declaration restriction. I cannot come up with a use for _Alignas that would
affect h2bi (nor can I come up with a proper translation).
What's left in terms of changes to the C standard is an extra unary operator
and changes in unicode string literals.
The unary operator is called
_Alignof(type-name)I think changes in the C expression syntax have some impact on h2bi as it has to deal with
constant - expressions. An example of constant-expressions h2bi has to deal with are the
constant-expressions found in enumeration members. Operators like <<, >>, +, - etc....
should be translated to their fb equivalent.
_Alignof(type-name) can be used in a constant expression so h2bi might have to translate
_Alignof(type-name) to some fb equivalent. The result of _Alignof(type-name) should be a
number (integer). I don't see how _Alignof and _Alignas can be translated to fb.
Last and least unicode string literals. Unicode support has always come in the form of the
wchar_t type (and a bunch of wchar_t related functions).
You could already use a string prefix (L) to denote that the content of a string literal
should be interpreted as having type wchar_t. C11 adds 3 more string prefixes: u8 u and U.
u8 denotes an UTF8 encoded string (type: char)
u denotes an UTF16 encoded string (type: char16_t)
U denotes an UTF32 encoded string (type: char32_t)
L denotes a wchar_t encoded string (type: wchar_t)
Character constants cannot be prefixed with u8.
In short: C11 still allows you to use L"hello world" but adds the possibility to use
u8"Hello World", u"Hello World" and U"Hello World". And the uchar.h header contains
prototypes for functions to
-- convert from multi byte character to char16_t or char32_t;
-- convert from char16_t to multi bytecharacter/convert from char32_t to multibyte character.
I don't know what to make of these new Unicode related additions. Unicode support in C has always
been lousy. Or to put it in the words of a C programmer:
Well, the support for wide characters in C and C++ has been somewhat erratic and inconsistent.
Which is why you find lots of unicode related code in glib. Relying on the C standard for unicode
support just isn't a good idea.
But string prefixes are part of C11, C programmers can use them (gcc supports use of the new
string prefixes) and h2bi should be able to deal with the new literal prefixes.
I don't think I have been very thorough in dealing with the C11 standard as it impacts h2bi
development. I do think few (if any) changes in the C standard affect h2bi beyond having to
recognize some more keywords that can subsequently be dropped during translation. C11
has only been around for a couple of years now (ever since december 2011) and gcc has only
recently started to implement things like _Generic (see next piece of code).
Which brings me to a new feature that impacts the translation of macros.
It's an addition to the primary expression section of the C syntax definition.
It looks like this (syntax)
generic-selection ::=
_Generic(assignment-expression
,generic-assoc-list
)generic-assoc-list ::= generic-association
generic-assoc-list ::= generic-assoc-list
, generic-association
generic-association ::= type-name
: assignment-expression
generic-association ::=
default: assignment-expression
An example
Code: Select all
_Generic( 'a', char: 1, int: 2, long: 3, default: 0)
The above code would evaluate to 2 (as character constants are type int in C).
In a macro you could use _Generic like so
Code: Select all
#define type_idx(T) _Generic( (T), char: 1, int: 2, long: 3, default: 0)
type_idx('a') evaluates to 2 and type_idx("a") evaluates to 0.
The above example and more can be found here
http://www.robertgamble.net/2012/01/c11 ... tions.htmlHope this post helps out making h2bi C11 - 'proof'.