Defined in the C standard is an optionally-supported keyword fortran
C99 language standard, section J.5.9:
The fortran function specifier may be used in a function declaration to indicate that calls suitable for FORTRAN should be generated, or that a different representation for the external name is to be generated.
This section remains unchanged in the C11 standard.
Nowhere else in either standard says anything else about this keyword. This section references section 6.7.4, Function Specifiers, which is what it seems to be, but the only one is inline, and the language involved tailors to that, and how one might use fortran isn't apparent.
The keyword is contained in the "Common Extensions" section (!), so universal support is not expected, and indeed, it is not present: my copy of GCC 7.2.0 doesn't recognize it.
Since I can't seem to use it,
a) How would one use the fortran keyword in C code?
b) What compilers support/supported this keyword?
The BC4.5 compiler for DOS/Win16 supports said keyword. It changes the calling convention of the function to FORTRAN's calling convention. Use looks like this:
extern fortran int FUNCTION(int *a, int *b, int *c);
(variables are passed by reference in FORTRAN).
You can also export a function to be called from FORTRAN like so:
fortran int FUNCTION2(int *a, int *b, int *c)
{
/* your code here */
}
I actually used it to call into QBX (BASIC), which uses almost exactly the same calling convention. The pascal keyword was better for this purpose; otherwise arguments come in backwards.
Related
I know there are two types of functions: void and the ones that return something (int, double, etc). But what if a function is declared without any return statements? Is it considered to be a void function? For example,
myFunction(int value){
.......
}
A function declared without any return type is considered returning an int. This is an ancient rule going back to the original K&R C, left in the language for backward compatibility.
Integer promotions and conversion of float arguments to doubles are done for functions without prior definition or forward declaration for the same reason - backward compatibility with really old code.
It is needless to say that relying on these rules for new development is a very bad practice. One should always declare return type explicitly, and forward-declare or define all functions before calling them.
First off, I have to say that your code:
myFunction(int value){
.......
}
is a function definition, other than just a declaration. A pure declaration will be like:
myFunction(int value);
or
myFunction(int); //also valid but less recommended due to bad readability
Also note that every definition can serve as a declaration of the function, but not vise versa.
Let's go back to your question. myFunction(int value); is equal to int myFunction(int value); according to earlier standards. In fact, compilers will assume all undeclared functions to return an int using these standards.
However, a prototype without a type isn't a function declaration since C99, although the type is very likely to still be seen as int by a compiler.
Any way, this is a very bad coding style and should be avoided, because compile-time checking cannot be performed and you are depending on undefined behaviors, which are never trustworthy. If you don't need a return value, you can just write:
void myFunction(int value);
See also: Are prototypes required for all functions in C89, C90 or C99?
If your standard compiler is set to correctly to compile according to the C standard, such functions are not allowed.
For example gcc -std=c11 -pedantic-errors -Wall.
If you have a 20+ year old compiler, such functions were allowed though. The return type would then default to int if not stated explicitly. Similarly if no function prototype was visible, the compiler would make up a nonsense function declaration based on the function call, where the return type would default to int, if no prototype was visible.
There was never any rationale for why the "implicit int" feature made sense. What it did in practice was to block the compiler from static type checks and therefore created countless of bugs.
The dangerous, "implicit int" was therefore promptly removed from the C language in 1999.
This is actually one of the main reasons why you shouldn't be using a C compiler that follows some ancient version of the C language in the year 2016.
I read several questions in stackoverflow about inline in C but still am not clear about it.
static inline void f(void) {} has no practical difference with static void f(void) {}.
inline void f(void) {} in C doesn't work as the C++ way. How does it work in C?
What actually does extern inline void f(void); do?
I never really found a use of the inline keyword in my C programs, and when I see this keyword in other people's code, it's almost always static inline, in which I see no difference with just static.
A C code can be optimized in two ways: For Code size and for Execution Time.
inline functions:
gcc.gnu.org says,
By declaring a function inline, you can direct GCC to make calls to that function faster. One way GCC can achieve this is to integrate that function's code into the code for its callers. This makes execution faster by eliminating the function-call overhead; in addition, if any of the actual argument values are constant, their known values may permit simplifications at compile time so that not all of the inline function's code needs to be included. The effect on code size is less predictable; object code may be larger or smaller with function inlining, depending on the particular case.
So, it tells the compiler to build the function into the code where it is used with the intention of improving execution time.
If you declare Small functions like setting/clearing a flag or some bit toggle which are performed repeatedly, inline, it can make a big performance difference with respect to time, but at the cost of code size.
non-static inline and Static inline
Again referring to gcc.gnu.org,
When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.
extern inline?
Again, gcc.gnu.org, says it all:
If you specify both inline and extern in the function definition, then the definition is used only for inlining. In no case is the function compiled on its own, not even if you refer to its address explicitly. Such an address becomes an external reference, as if you had only declared the function, and had not defined it.
This combination of inline and extern has almost the effect of a macro. The way to use it is to put a function definition in a header file with these keywords, and put another copy of the definition (lacking inline and extern) in a library file. The definition in the header file causes most calls to the function to be inlined. If any uses of the function remain, they refer to the single copy in the library.
To sum it up:
For inline void f(void){},
inline definition is only valid in the current translation unit.
For static inline void f(void) {}
Since the storage class is static, the identifier has internal linkage and the inline definition is invisible in other translation units.
For extern inline void f(void);
Since the storage class is extern, the identifier has external linkage and the inline definition also provides the external definition.
Note: when I talk about .c files and .h files in this answer, I assume you have laid out your code correctly, i.e. .c files only include .h files. The distinction is that a .h file may be included in multiple translation units.
static inline void f(void) {} has no practical difference with static void f(void) {}.
In ISO C, this is correct. They are identical in behaviour (assuming you don't re-declare them differently in the same TU of course!) the only practical effect may be to cause the compiler to optimize differently.
inline void f(void) {} in C doesn't work as the C++ way. How does it work in C? What actually does extern inline void f(void); do?
This is explained by this answer and also this thread.
In ISO C and C++, you can freely use inline void f(void) {} in header files -- although for different reasons!
In ISO C, it does not provide an external definition at all. In ISO C++ it does provide an external definition; however C++ has an additional rule (which C doesn't), that if there are multiple external definitions of an inline function, then the compiler sorts it out and picks one of them.
extern inline void f(void); in a .c file in ISO C is meant to be paired with the use of inline void f(void) {} in header files. It causes the external definition of the function to be emitted in that translation unit. If you don't do this then there is no external definition, and so you may get a link error (it is unspecified whether any particular call of f links to the external definition or not).
In other words, in ISO C you can manually select where the external definition goes; or suppress external definition entirely by using static inline everywhere; but in ISO C++ the compiler chooses if and where an external definition would go.
In GNU C, things are different (more on this below).
To complicate things further, GNU C++ allows you to write static inline an extern inline in C++ code... I wouldn't like to guess on what that does exactly
I never really found a use of the inline keyword in my C programs, and when I see this keyword in other people's code, it's almost always static inline
Many coders don't know what they're doing and just put together something that appears to work. Another factor here is that the code you're looking at might have been written for GNU C, not ISO C.
In GNU C, plain inline behaves differently to ISO C. It actually emits an externally visible definition, so having a .h file with a plain inline function included from two translation units causes undefined behaviour.
So if the coder wants to supply the inline optimization hint in GNU C, then static inline is required. Since static inline works in both ISO C and GNU C, it's natural that people ended up settling for that and seeing that it appeared to work without giving errors.
, in which I see no difference with just static.
The difference is just in the intent to provide a speed-over-size optimization hint to the compiler. With modern compilers this is superfluous.
From 6.7.4 Function specifiers in C11 specs
6 A function declared with an inline function specifier is an inline
function. Making a function an inline function suggests that calls to
the function be as fast as possible.138)The extent to which
such suggestions are effective is
implementation-defined.139)
138) By using, for example, an alternative to the usual function call
mechanism, such as inline substitution. Inline substitution is not
textual substitution, nor does it create a new function. Therefore,
for example, the expansion of a macro used within the body of the
function uses the definition it had at the point the function body
appears, and not where the function is called; and identifiers refer
to the declarations in scope where the body occurs. Likewise, the
function has a single address, regardless of the number of inline
definitions that occur in addition to the external
definition.
139) For example, an implementation might
never perform inline substitution, or might only perform inline
substitutions to calls in the scope of an inline declaration.
It suggests compiler that this function is widely used and requests to prefer speed in invocation of this function. But with modern intelligent compiler this may be more or less irrelevant as compilers can decide whether a function should be inlined and may ignore the inline request from users, because modern compilers can very effectively decide about how to invoke the functions.
static inline void f(void) {} has no practical difference with static
void f(void) {}.
So yes with modern compilers most of the time none. With any compilers there are no practical / observable output differences.
inline void f(void) {} in C doesn't work as the C++ way. How does it
work in C?
A function that is inline anywhere must be inline everywhere in C++ and linker does not complain multiple definition error (definition must be same).
What actually does extern inline void f(void); do?
This will provide external linkage to f. Because the f may be present in other compilation unit, a compiler may choose different call mechanism to speed up the calls or may ignore the inline completely.
A function where all the declarations (including the definition) mention inline and never extern.
There must be a definition in the same translation unit. The standard refers to this as an inline definition.
No stand-alone object code is emitted, so this definition can't be called from another translation unit.
In this example, all the declarations and definitions use inline but not extern:
// a declaration mentioning inline
inline int max(int a, int b);
// a definition mentioning inline
inline int max(int a, int b) {
return a > b ? a : b;
}
Here is a reference which can give you more clarity on the inline functions in C & also on the usage of inline & extern.
If you understand where they come from then you'll understand why they are there.
Both "inline" and "const" are C++ innovations that were eventually retrofit into C. One of the design goals implicit in these innovations, as well as later innovations, like template's and even lambda's, was to carve out the most common use-cases for the pre-processor (particularly, of "#define"), so as to minimize the use of and need for the pre-processor phase.
The occurrence of a pre-processor phase in a language severely limits the ability to provide transparency in the analysis of and translation from a language. This turned what ought to have been easy translation shell scripts into more complicated programs, such as "f2c" (Fortran to C) and the original C++ compiler "cfront" (C++ to C); and to a lesser degree, the "indent" utility. If you've ever had to deal with the translation output of convertors like these (and we have) or with actually making your own translators, then you'll know how much of an issue this is.
The "indent" utility, by the way, balks on the whole issue and just wings it, compromising by just treating macros calls as ordinary variables or function calls, and passing over "#include"'s. The issue will also arise with other tools that may want to do source-to-source conversion/translation, like automated re-engineering, re-coding and re-factoring tools; that is, things that more intelligently automate what you, the programmer, do.
So, the ideal is to reduce dependency on the pre-processor phase to a bare minimum. This is a goal that is good in its own right, independently of how the issue may have been encountered in the past.
Over time, as more and more of the use-cases became known and even standardized in their usage, they were encapsulated formally as language innovations.
One common use-case of "#define" to create manifest constants. To a large extent, this can now be handled be the "const" keyword and (in C++) "constexpr".
Another common use-case of "#define" is to create functions with macros. Much of this is now encapsulated by the "inline" function, and that's what it's meant to replace. The "lambda" construct takes this a step further, in C++.
Both "const" and "inline" were present in C++ from the time of its first external release - release E in February 1985. (We're the ones who transcribed and restored it. Before 2016, it only existed as a badly-clipped printout of several hundred pages.)
Other innovations were added later, like "template" in version 3.0 of cfront (having been accepted in the ANSI X3J16 meeting in 1990) and the lambda construct and "constexpr" much more recently.
As the word "Inline" say "In" "Line", adding this keyword to a function affects the program in runtime, when a program is compiled, the code written inside a function is pasted under the function call, as function calls are more costly than inline code, so this optimizes the code.
So, static inline void f(void) {} and static void f(void) {}, here the inline keyword does make a difference in runtime. But when the function has too many lines of code then it won't affect runtime.
If you add static before a function, the function's lifetime is the lifetime of the whole program. And that function use is restricted to that file only.
To know about extern you can refer to - Effects of the extern keyword on C functions
In every C program I had seen, there will be the main() function. Unlike in other languages, such as Java and C++, it has no data type before it. In C++ and Java there will at least be a void with main(), if not some other data type.
Why does main() have no data type with it in C?
Also, in Java the constructor has no data type used with it. Is it possible to return any value if no data type is used before functions? Or by default, can they return any value?
It's user-defined: you define it in each program. If it were a library function, you wouldn't define it, because the library would define it for you.
(As an exception to this, the Unix libraries libl and liby, the support libraries for Lex and Yacc, actually define main; the idea is that you define a bunch of functions with standard names and you get a default main that calls these functions. You can override their main, though. Apparently Windows compilers do something similar.)
main() is a user-defined function.
Standard clearly states that it is a user defined function:
C11: 5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:....
main() is always user defined, and can be prototyped in many ways (although some will argue that point)
(edited)
main(void){/*User defined content*/} // K&R implied `int` return type
void main(void){/*User defined content*/} //yeah, yeah, I know
int main(void){/*User defined content*/ return 0;} //commonly used
int main(int argc, char *argv[]){/*User defined content*/ return 0;} //commonly used
I use a C99 implementation of a C compiler. While it very explicitly notifies of any warning or error for illegal or nefarious syntax, It did not flag the following scenario:
So, while it is not strictly conforming, it is evidently not illegal.
Recently while learning about c programming i noticed something that i found interesting. I had read that a statement like int i=0; is the only way to force a definition while a statement like extern int i; implies a forced declaration. A statement like int i; would be context dependent. But what happens when i combine the the extern with initialization like extern int i=13;. Compiler generates a warning. But what is this rule governing this?
This is a Coding style warning.
The argument for this is the code is valid, but extremely unidiomatic for C since "extern" is generally expected to mean that the declaration is not providing a definition of the object.
extern int i=13;
declares and defines i, While:
extern int i;
just declares the variable i.
A specific bug 45977 has been raised on GCC on the same but it is still shows Unconfirmed Status.
The bug report points out that the code is syntactically as per the C standard. And it has an discussion which discusses this in detail.
For Standerdese Fans:
Relevant Section References are:
ansi c99 Standard 6.2.2: Linkage Of Identifiers and
ansi c99 Standard 6.9.2.4
When you declare a variable you just bind a name to it.
When you define a variable you reserve memory for it.
When you declare a variable as extern you are telling the compiler "this is defined elsewhere and will be available on linking time", so it's OK to use it.
Extern is used if you want to access particular variable from different program. As you don't have any definition for that in you program your complier is giving you an error.
In C, a definition is just a declaration that happens to allocate storage (whether it is because it has an initializer, or because it is a tentative definition that gets used as a definition). So, everything that you can do to a declaration (like specifying it has extern storage), you can also do to a definition.
Note that this differs from C++.
int _cdecl f (int x) { return 0; }
int _stdcall f (int y) { return 0; }
After name mangling will be:
_f
_f#4
Which doesn't conflict, is this allowed in c ,if not, why?
The keywords _cdecl and _stdcall are not part of the C language. These are Microsoft extensions which were preceded by similar Borland extensions.
In the standard C language, you can't declare a calling convention. Every function declared is, obviously, equivalent to what the MS compiler refers to as the "_cdecl" convention.
It would be possible to use in-line assembly to distinguish the two functions when you call them. Because you're using a platform-specific vendor extension of C, you might consider using in-line assembly.
First off, that's not mangling, that's decoration. Mangling is something that happens with C++ compilers because C++ was originally designed to to support overloading using C style link tools.
As to your question, you can't have two functions with the same name. For the purposes of applying that rule, the un-decorated name is used.
Why is this so? I'd imagine it is because decoration and calling conventions are not part of the C standard and are specific to each compiler. I'm pretty sure that C compilers supporting multiple calling conventions only came in to being a number of years after C was invented.