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.
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...
Most keywords in C (or in any language for that matter) starts with a letter. But there are some keywords that starts with an underscore? They keywords are: _Alignas, _Alignof, _Atomic, _Bool, _Complex, _Generic, _Imaginary, _Noreturn, _Static_assert and _Thread_local.
I find it amazingly strange. If it was a hidden global constant or internal function that's not really a part of the API, I would understand it. But these are keywords.
I find it extra strange when C actually have a macros called bool and static_assert, and that their implementations is using the very keywords I just mentioned.
C developed and become very popular before it was planned by a standards committee. In consequence, there was a lot of existing code.
When setting a C standard, or updating an old standard, an important goal is not to “break” old code. It is desirable that code that worked with previous compilers continue to work with new versions of the C language.
Introducing a new keyword (or any new definition or meaning of a word) can break old code, since, when compiling, the word will have its new keyword meaning and not the identifier meaning it had with the previous compilers. The code will have to be edited. In addition to the expense of paying people to edit the code, this has a risk of introducing bugs if any mistakes are made.
To deal with this, a rule was made that identifiers starting with underscore were reserved. Making this rule did not break much old software, since most people writing software choose to use identifiers beginning with letters, not underscore. This rule gives the C standard a new ability: By using underscore when adding new keywords or other new meanings for words, it is able to do so without breaking old code, as long as that old code obeyed the rule. For example, adding a new keyword, _Bool for a Boolean type, would not break any code that had not used identifiers beginning with an underscore.
New versions of the C standard sometimes introduce new meanings for words that do not begin with an underscore, such as bool. However, these new meanings are generally not introduced in the core language. Rather, they are introduced only in new headers. In making a bool type, the C standard provided a new header, <stdbool.h>. Since old code could not be including <stdbool.h> since it did not exist when the code was written, defining bool in <stdbool.h> would not break old code. At the same time, it gives programmers writing new code the ability to use the new bool feature by including <stdbool.h>, which defines bool as a macro that is replaced by _Bool.
In the standard, any name that begins with a double underscore or an underscore followed by an uppercase letter is reserved. This is useful because C lacks named namespaces. By reserving all such symbols, new and implementation specific keywords can be introduced to the language without clashing with symbols defined in existing code.
The macros such as bool and static_assert are "convenience macros", they allow you to use the reserved keyword symbols without the underscores and capitals at the small risk of a name clash. However they provide a means to resolve a name clash because unlike a keyword, and macro may be #undefined, or the header that defines it excluded and the internal keyword used directly. Moreover unmodified legacy code will not be broken because by definition it will not include the headers that did not exist at the time of writing
The unadorned keywords have been defined in the language since the language's inception (with the exception of inline and restrict defined since C99), so will not cause a conflict with legacy code symbols. All _Xxxx keywords have been defined at or since C99.
Unlike many languages in common use today, C has been around since the 1970's and standardised since 1989 - there is a huge amount of existing code that must remain compilable on modern compilers while at the same time the language cannot remain unchanged - if it did it might no longer be in such common use.
Eric and Clifford has provided good answers, but I add a quote from the C11 standard to support it.
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.
https://port70.net/~nsz/c/c11/n1570.html#7.1.3
One might also consider this:
Typedef names beginning with int or uint and ending with _t may be added to the types defined in the stdint.h header. Macro names beginning with INT or UINT and ending with _MAX, _MIN, or _C may be added to the macros defined in the stdint.h header.
https://port70.net/~nsz/c/c11/n1570.html#7.31.10p1
This is from a textbook:
/* This function locates the address of where a new structure
should be inserted within an existing list.
It receives the address of a name and returns the address of a
structure of type NameRec
*/
struct NameRec *linear Locate(char *name)
{
...
}
I understand it returns a pointer to a struct NameRec. Why is "linear" there and why is there a space between "linear" and "Locate"?
#define linear
will make it syntactically correct even if it wasn't before (though, technically, you'd probably want a #undef linear beforehand to avoid possible conflicting macro definitions).
It depends entirely on the context of the code, which you haven't shown. As it stands now, with no header inclusions or definitions like -Dlinear= on the compiler command line, it would not compile in a standards-conformant environment without extensions.
The best way to tell, of course, is to just try to actually compile the thing and see what happens :-)
Given that the solutions link for chapter 13 (the one you're asking about) has no mention of the linear word in the solution, I'd say it's a safe bet to assume your book is incorrect. I'd consider contacting the author (apparently currently working at FDU in New Jersey) to clear it up.
It's a typo in the book. See the locate function here:
https://users.ipfw.edu/chansavj/ACY2017/ANSI_C/ANSI_C_4thEd/Solutions%20to%20Exercises%20(Windows)/Solutions/83556-0s/Ch13/pgm13-5ex3.c
(Posted by ta.speot.is in the comments)
So I'm completely new to programming. I currently study computer science and have just read the first 200 pages of my programming book, but there's one thing I cannot seem to see the difference between and which havn't been clearly specified in the book and that's reserved words vs. standard identifiers - how can I see from code if it's one or the other.
I know the reserved words are some that cannot be changed, while the standard indentifiers can (though not recommended according to my book). The problem is while my book says reserved words are always in pure lowercase like,
(int, void, double, return)
it kinda seems to be the very same for standard indentifier like,
(printf, scanf)
so how do I know when it is what, or do I have to learn all the reserved words from the ANSI C, which is the current language we are trying to learn, (or whatever future language I might work with) to know when it is when?
First off, you'll have to learn the rules for each language you learn as it is one of the areas that varies between languages. There's no universal rule about what's what.
Second, in C, you need to know the list of keywords; that seems to be what you're referring to as 'reserved words'. Those are important; they're immutable; they can't be abused because the compiler won't let you. You can't use int as a variable name; it is always a type.
Third, the C preprocessor can be abused to hijack anything; if you compile with #define double int in effect, you get what you deserve, but there's nothing much to stop you doing that.
Fourth, the only predefined variable name is __func__, the name of the current function.
Fifth, names such as printf() are defined by the standard library, but the standard library has to be implemented by someone using a C compiler; ask the maintainers of the GNU C library. For a discussion of many of the ideas behind the treaty between the standard and the compiler writers, and between the compiler writers and the programmers using a compiler, see the excellent book The Standard C Library by P J Plauger from 1992. Yes, it is old and the modern standard C library is somewhat bigger than the one from C90, but the background information is still valid and very helpful.
Reserved words are part of the language's syntax. C without int is not C, but something else. They are built into the language and are not and cannot be defined anywhere in terms of this particular language.
For example, if is a reserved keyword. You can't redefine it and even if you could, how would you do this in terms of the C language? You could do that in assembly, though.
The standard library functions you're talking about are ordinary functions that have been included into the standard library, nothing more. They are defined in terms of the language's syntax. Also, you can redefine these functions, although it's not advised to do so as this may lead to all sorts of bugs and unexpected behavior. Yet it's perfectly valid to write:
int puts(const char *msg) {
printf("This has been monkey-patched!\n");
return -1;
}
You'd get a warning that'd complain about the redefinition of a standard library function, but this code is valid anyway.
Now, imagine reimplementing return:
unknown_type return(unknown_type stuff) {
// what to do here???
}
Is it legal to forward declare structs and functions provided by the C standard library?
My background is C++ in which the answer is no. The primary reason for this is that a struct or class mandated by the C++ standard library can be a template behind the scenes and may have "secret" template parameters and so cannot be properly declared with a naive non-template declaration. Even if a user does figure out exactly how to forward declare a particular entity in a particular version of a particular implementation, the implementation is not obliged to not break that declaration in future versions.
I don't have a copy of any C standard at hand but obviously there are no templates in C.
So is it legal to forward declare entities in the C standard library?
Another reason that entities in the C++ standard library may not be forward declared is that headers provided by the implementation need not follow the normal rules. For example, in a recent question I asked if a C++ header provided by the implementation need be an actual file and the answer was no. I don't know if any of that applies to C.
The C standard library is used by both C and C++ but for this question I'm only asking about C.
Forward declarations of structs are always permissible in C. However, not very many types can be used this way. For example, you can't use a forward declaration for FILE simply because the tag name of the struct is not specified (and theoretically, it may not be a struct at all).
Section 7.1.4 paragraph 2 of n1570 gives you permission to do the same with functions:
Provided that a library function can be declared without reference to any type defined in a
header, it is also permissible to declare the function and use it without including its
associated header.
This used to be rather common. I think the reasoning here is that hard drives are slow, and fewer #include means faster compile times. But this isn't the 1980s any more, and we all have fast CPUs and fast hard drives, so a few #include aren't even noticed.
void *malloc(size_t);
void abort(void);
/* my code here */
yes you can this is perfectly valid.
this can be done with the standard library too.
double atof(const char *);
int main() {
double t = atof("13.37");
return 0;
}
#include <stdio.h>
Similiar things can be done with structs, variables etc.
I would recommend you read the wiki page which features some c examples:
http://en.wikipedia.org/wiki/Forward_declaration
this is specified in the c standard, Section 7.1.4 paragraph 2 of n1570
Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.