I am studying "include/asm-x86/types.h" and I'm a little confused about the meaning of \__signed__.
When I Google this keyword, I cannot get any useful information. Why not just use signed instead of \__signed__, does it have a special meaning?
That is used for backwards compatibility, when older compilers didn't recognize signed keyword, such alternatives were used.
The difference between __signed__ and signed is to do with namespaces. The signed names are only available in the __KERNEL__ and not outside.
As stated at the top of the header file you mention:
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
* header files exported to user space
*/
For the signed names without underscores it states this:
/*
* These aren't exported outside the kernel to avoid name space clashes
*/
__signed__ is also used for compile with gcc -traditional, where the keyword signedis not recognized.
Don't google using c __signed__, because special characters like __ are skipped in the search, do a literal search using c "__signed__" and you will get useful information.
Related
I am trying to understand when a developer needs to define a C variable with preceding '_'. What is the reason for it?
For example:
uint32_t __xyz_ = 0;
Maybe this helps, from C99, 7.1.3 ("Reserved Identifiers"):
All identifiers that begin with an underscore and either an uppercase letter or another
underscore are always reserved for any use.
All identifiers that begin with an underscore are always reserved for use as identifiers
with file scope in both the ordinary and tag name spaces.
Moral: For ordinary user code, it's probably best not to start identifiers with an underscore.
(On a related note, I think you should also stay clear from naming types with a trailing _t, which is reserved for standard types.)
It is a trick used in the header files of C implementations for global symbols, in order to prevent eventual conflicts with other symbols defined by the user.
Since C lacks a namespace feature, this is a rudimentary approach to avoid name collisions with the user.
Declaring such symbols in your own header and source files is not encouraged because it can introduce naming conflicts between your code and the C implementation. Even if that doesn't produce a conflict on your current implementation, you are still prone to strange conflicts across different/future implementations, since they are free to use other symbols prefixed with underscores.
whether its C or not, the leading underscore provides the programmer a status indication so he does not have to go look it up. In PHP, or any object oriented language where we deal with tens of thousands of properties and methods written by 1000's of authors, seeing an underscore prefix removes the need to go dig through the class andlook up whether its declared private, or protected or public. thats an immense time saver. the practice started before C, i am sure...
I'm experiencing a problem with documenting the variables containing the double$ ("$$") in the name. In fact these names are not real variables but rather the Keil Linker-generated constants. The $$ appears to have a special (undocumented?) meaning for the Doxygen parser. If I write the following code
extern char SectionA$$Base[]; /** starting address of the section **/
extern char SectionA$$Limit[]; /** end address of the section **/
Doxygen complains about the undocumented variables $$Base and $$Limit, includes it in the documentation with the names where the $$ is prepend by space using weird combinations of bold, link and so on attributes and without any comment. The total quantity of the variables declared this way is 8. Nevertheless the documentation output contains 2 or sometimes 4 of the declarations. So $$ apears to have a big influence I don't understand.
How can I force Doxygen to treat this variables like any other one?
As far as I am aware, Doxygen has no command or configuration option for accepting invalid identifiers. It does, however, support filtering input files prior to processing them. You could perhaps use that to alter the offending declarations, or to remove them from among those passed on to Doxygen. See the INPUT_FILTER, FILTER_PATTERNS, and related configuration options.
Alternatively, you could put the offending declarations in a separate header, and omit that header from Doxygen processing (EXCLUDE and or EXCLUDE_PATTERNS can help).
I don't see a way to use Doxygen to actually generate documentation for these identifiers.
I recently got a snippet of code in Linux kernel:
static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__acquires(&info->lock)
__releases(&info->lock)
{
...
}
What confused me is the two __functions following static int fb_mmap() right before "{",
a).What is the purpose of the two __funtions?
b).Why in that position?
c).Why do they have the prefix "__"?
d).Are there other examples similar to this?
Not everything ending with a pair of parenthesis is a function (call). In this case they are parameterized macro expansions. The macros are defined as
#define __acquires(x) __attribute__((context(x,0,1)))
#define __releases(x) __attribute__((context(x,1,0)))
in file include/linux/compiler.h in the kernel build tree.
The purpose of those macros expanding into attribute definitions is to annotate the function symbols with information about which locking structures the function will acquire (i.e. lock) and release (i.e. unlock). The purpose of those in particular is debugging locking mechanisms (the Linux kernel contains some code that allows it to detect potential deadlock situations and report on this).
https://en.wikipedia.org/wiki/Sparse
__attribute__ is a keyword specific to the GCC compiler, that allows to assign, well, attributes to a given symbol
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes
Since macros are expanded at the text level, before the compiler is even looking at it, the result for your particular snippet, that the actual compilers sees would be
static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__attribute__((context(&info->lock,0,1)))
__attribute__((context(&info->lock,1,0)))
{
…
}
Those macros start with a double underscore __ to indicate, that they are part of the compiler environment. All identifiers starting with one or two underscores are reserved for the compiler environment implementation. In the case of the Linux kernel, because Linux is a operating system kernel that does not (because it simply is not availible) use the standard library, it's natural for it, do define it's own compiler environment definitions, private to it. Hence the two underscores to indicate, that this is compiler environment/implementation specific stuff.
They're probably macros defined with #define. You should look for the definition of such macros and see what they expand to. They might expand to some pragma giving hints to the compiler; they might expand to nothing giving hints to the developers or some analysis tool. The meaning might vary
The __attribute__ these macros evaluate to are compiler-specific features. man gcc explains some of the uses.
The prefix __ typically is used to avoid name clashes; double underscore as prefix and postfix mark an identifier as being used by the compiler itself.
More on gcc attributes can be found here.
More on the kernel use of these can be found here.
Those are macro's defined as
# define __acquires(x) __attribute__((context(x,0,1)))
# define __releases(x) __attribute__((context(x,1,0)))
in Linux/include/linux/compiler.h
I'm new to C and looking at Go's source tree I found this:
https://code.google.com/p/go/source/browse/src/pkg/runtime/race.c
void runtime∕race·Read(int32 goid, void *addr, void *pc);
void runtime∕race·Write(int32 goid, void *addr, void *pc);
void
runtime·raceinit(void)
{
// ...
}
What do the slashes and dots (·) mean? Is this valid C?
IMPORTANT UPDATE:
The ultimate answer is certainly the one you got from Russ Cox, one of Go authors, on the golang-nuts mailing list. That said, I'm leaving some of my earlier notes below, they might help to understand some things.
Also, from reading this answer linked above, I believe the ∕ "pseudo-slash" may now be translated to regular / slash too (like the middot is translated to dot) in newer versions of Go C compiler than the one I've tested below - but I don't have time to verify.
The file is compiled by the Go Language Suite's internal C compiler, which originates in the Plan 9 C compiler(1)(2), and has some differences (mostly extensions, AFAIK) to the C standard.
One of the extensions is, that it allows UTF-8 characters in identifiers.
Now, in the Go Language Suite's C compiler, the middot character (·) is treated in a special way, as it is translated to a regular dot (.) in object files, which is interpreted by Go Language Suite's internal linker as namespace separator character.
Example
For the following file example.c (note: it must be saved as UTF-8 without BOM):
void ·Bar1() {}
void foo·bar2() {}
void foo∕baz·bar3() {}
the internal C compiler produces the following symbols:
$ go tool 8c example.c
$ go tool nm example.8
T "".Bar1
T foo.bar2
T foo∕baz.bar3
Now, please note I've given the ·Bar1() a capital B. This is
because that way, I can make it visible to regular Go code - because
it is translated to the exact same symbol as would result from
compiling the following Go code:
package example
func Bar1() {} // nm will show: T "".Bar1
Now, regarding the functions you named in the question, the story goes further down the rabbit hole. I'm a bit less sure if I'm right here, but I'll try to explain based on what I know. Thus, each sentence below this point should be read as if it had "AFAIK" written just at the end.
So, the next missing piece needed to better understand this puzzle, is to know something more about the strange "" namespace, and how the Go suite's linker handles it. The "" namespace is what we might want to call an "empty" (because "" for a programmer means "an empty string") namespace, or maybe better, a "placeholder" namespace. And when the linker sees an import going like this:
import examp "path/to/package/example"
//...
func main() {
examp.Bar1()
}
then it takes the $GOPATH/pkg/.../example.a library file, and during import phase substitutes on the fly each "" with path/to/package/example. So now, in the linked program, we will see a symbol like this:
T path/to/package/example.Bar1
The "·" character is \xB7 according to my Javascript console.
The "∕" character is \x2215.
The dot falls within Annex D of the C99 standard lists which special characters which are valid as identifiers in C source. The slash doesn't seem to, so I suspect it's used as something else (perhaps namespacing) via a #define or preprocessor magic.
That would explain why the dot is present in the actual function definition, but the slash is not.
Edit: Check This Answer for some additional information. It's possible that the unicode slash is just allowed by GCC's implementation.
It appears this is not standard C, nor C99. In particular, it both gcc and clang complain about the dot, even when in C99 mode.
This source code is compiled by the Part 9 compiler suite (in particular, ./pkg/tool/darwin_amd64/6c on OS X), which is bootstrapped by the Go build system. According to this document, bottom of page 8, Plan 9 and its compiler do not use ASCII at all, but use Unicode instead. At bottom of page 9, it it stated that any character with a sufficiently high code point is considered valid for use in an identifier name.
There's no pre-processing magic at all - the definition of functions do not match the declaration of functions simply because those are different functions. For example, void runtime∕race·Initialize(); is an external function whose definition appears in ./src/pkg/runtime/race/race.go; likewise for void runtime∕race·MapShadow(…).
The function which appears later, void runtime·raceinit(void), is a completely different function, which is aparant by the fact it actually calls runtime∕race·Initialize();.
The go compiler/runtime is compiled using the C compilers originally developed for plan9. When you build go from source, it'll first build the plan9 compilers, then use those to build Go.
The plan9 compilers support unicode function names [1], and the Go developers use unicode characters in their function names as pseudo namespaces.
[1] It looks like this might actually be standards compliant: g++ unicode variable name but gcc doesn't support unicode function/variable names.
While cruising through my white book the other day, I noticed in the list of C keywords.
entry is one of the keywords on that list.
It is reserved for future use. Thinking back to my Fortran days, there was a function of some sort that used an entry statement to make a second argument signature, or entry point into a function.
Is this what entry was originally intended to be used for? or something completely different?
What is the story on the entry keyword?
I had no idea, so I googled to find something about this. This is what I found.
First, it was included as a reserved keyword.
Q: What was the entry keyword mentioned in K&R1?
A: It was reserved to allow functions with multiple, differently-named entry points, but it has been withdrawn.
(From http://archives.devshed.com/forums/c-c-134/c-programming-faqs-371017.html.)
It was never standardized; some compilers used it, in a very personal way.
It was later declared obsolete, I guess.
In FORTRAN, "ENTRY" could declare a second entry point into a subroutine. It was a structured programming nightware, and fortunately C decided not to adopt it.
The entry keyword came from PL/I and allowed multiple entry points into a function. The keyword was implemented by some compilers but was never standardized.
To complement the accepted answer 'entry' is mentioned in K&R1:
2.3 Keywords
The following identifiers are reserved for use as keywords, and may not be used otherwise
int extern else
char register for
float typedef do
double static while
struct goto switch
union return case
long sizeof default
short break entry
unsigned continue
auto if
and here:
The entry keyword is not currently implemented by any compiler but is
reserved for future use. Some implementations also reserve the words 'fortran'
and 'asm'.
Then in the Rationale for the ANSI C language (C89) it is mentioned here:
3.1.1 Keyword
[...]
The keywords 'entry' 'fortran', and 'asm' have not been included since they were either never used, or are not portable. Uses of 'fortran' and 'asm' as keywords are not as common extensions.