From my memory, mangling name is not used in C, which is kinda of a feature that we take advantage using C function for ABI (Application Binary Interface). But recently I have been reading this article about mangling name in C
https://gustedt.wordpress.com/2011/06/24/name-mangling-in-c/
Question here is, If in any case that compiler will mangle C function name?
Since C is a programming language that does not support name function overloading, it does no name mangling. But for compilers targeted at Microsoft Windows Platform, which has a variety of calling conventions like _cdecl,_stdcall etc. the function names are mangled to provide information regarding the calling convention.
For example,
int _stdcall fun(int myVar) {return 0;}
int _fastcall fun(int myVar){return 1;}
int _cdecl fun(int myVar){return 2;}
the compiler(32-bit) output will be like this:
_fun#4 /* _(function_name)#(argument_size_in_bytes) */
#fun#4 /* #(function_name)#(argument_size_in_bytes) */
_fun /* _(function_name) */
Function names won't be mangled, except apparently in the case of Unicode identifiers. For example:
// Mangled as "o_u03ba" using Intel's compiler "icc").
extern int o\u03ba(void);
The issue with icc highlighted by the blog article linked in the question is obviously a problem when the compiler generates non-unique symbol names:
//Both will have the same symbol name.
extern void o\u03ba(volatile int *p)
{
*p = -32767;
}
extern void o_u03ba(volatile int *p)
{
*p = 0;
}
...
volatile int n;
// Should print -32767; may print 0 or -32767.
o\u03ba(&n);
printf("%d\n", n);
// Should print 0; will print the same thing as the previous line.
o_u03ba(&n);
printf("%d\n", n);
Functions declared with the static keyword have internal linkage. Despite this, the compiler's internal representation may still use a mangled name, though you will never see it in the resulting program. When resolving references to functions, however, the code presented by the article indicates that even using the name at all can cause an issue:
static void foo\u03ba(volatile int n)
{
printf("foo\\u03ba: n = %d\n", n);
}
static void foo_u03ba(volatile int n)
{
printf("foo_u03ba: n = %d\n", n);
}
...
volatile int n = 10;
// These two lines may print the same thing.
foo\u03ba(n);
foo_u03ba(n);
Since you technically cannot take the address of a function and print it reliably, the best you can do is uniquely identify which function is called.
Related
Here's a code:
#include <stdio.h>
/* declaration */
int square (int num);
int main() {
int x, result;
x = 5;
result = square(x);
printf("%d squared is %d\n", x, result);
return 0;
}
/* definition */
int square (int num) {
int y;
y = num * num;
return(y);
}
And when I change it like this:
#include <stdio.h>
/* declaration */
int main() {
int x, result;
x = 5;
result = square(x);
printf("%d squared is %d\n", x, result);
return 0;
}
/* definition */
int square (int num);
int square (int num) {
int y;
y = num * num;
return(y);
}
I get the warning:
Implicit declaration of the function 'square'
Does this warning has any relation with the branch prediction things? Does the former code improves branch prediction and hence the performance of the code (as the function call branches/diverts the execution from the normal execution of the code!?)
No, it has nothing to do with branch prediction.
The language requires that a declaration of a function appear before the function is called. The compiler needs to see the declaration in order to generate code for the function call that is even correct, let alone performant: to know what types are expected as parameters, what type is returned, how the parameters should be laid out in the stack and registers, and so on. And by the one-pass design of the C language, this means the declaration has to appear before the function call. It's true that the necessary information is further down in the source file, but that's too late - the compiler isn't designed to "peek ahead" for it.
In modern C, the absence of the declaration makes the program invalid, and the compiler must issue a diagnostic. Previous versions of the C language allowed such a program to compile, using an "implicit declaration" which was essentially a standard set of rules to guess what types were expected and returned, and how they should be passed. Some compilers, such as gcc, proceed under these earlier rules when they find a missing declaration, and only give a warning instead of an error (which complies with the requirement for a diagnostic). But as the programmer, you really should consider it an error, since there's a good chance that the "guessed" implicit declaration will be wrong for your function, in which case the compiled program may fail in unpredictable ways at runtime.
I was going through Dennis Ritchie's book, The C programming language. In it, he says:
In certain circumstances, the extern declaration can be omitted. If the definition of the
external variable occurs in the source file before its use in a particular function, then there is no
need for an extern declaration in the function.
I tried quick code as follows:
#include "stdio.h"
int n = 0;
int nn = 111;
int main(int argc, char **argv) {
int n = 1;
printf("n from main(): %d\n", n);
function1();
function2();
}
void function1()
{
extern int n;
int nn; //declaring without extern keyword, this should point to global nn as per Dennis, but that does not seem to happen
int nnn; //declaring without extern keyword
printf("n from function1(): %d\n", n);
printf("nn from function1(): %d\n", nn);
printf("nnn from function1(): %d\n", nnn);
n = 10;
}
void function2()
{
extern int n;
int nn; //declaring without extern keyword, this should point to global nn as per Dennis, but that does not seem to happen
int nnn; //declaring without extern keyword
printf("n from function2(): %d\n", n);
printf("nn from function2(): %d\n", nn);
printf("nnn from function2(): %d\n", nnn);
}
int nnn = 222 ;
Below is sample output:
n from main(): 1
n from function1(): 0
nn from function1(): 1955388784
nnn from function1(): 6422476
n from function2(): 10
nn from function2(): 1955388784
nnn from function2(): 6422476
Notice what both functions function1() and function2() printed above. I guess, as per Dennis' statement, both should have referred global nn and should have printed 111. But that did not happen.
(You can try running code here)
Is it because the version about which Dennis is talking differs from the one using?
Am on MinGW.org GCC-8.2.0-5.
, then there is no need for an extern declaration in the function.
Here what Dennis Ritchie saying is that, If definition of nn varibale is already occured in source file then now in function1() and funcation2() you do not need to declare variable as extern again, like (extern int nn;) you can directly use them.
But by doing int nn; in your funcation1() you are defining one another local variable. Which is complete different variable.
The keyword extern is used with objects to reference objects that have file scope.
This declaration in your functions
int nn; //declaring without extern keyword, this should point to global nn as per Dennis, but that does not seem to happen
has a block scope. So it is a definition of a local variable.. It does not have linkage.
The quote you provided means that if there is a definition of a file scope variable then it has external or internal linkage. So there is no need to use the keyword extern
For example
//…
int n = 10; // definition of a variable with external linkage
void f()
{
printf( "n = %d\n", n );
}
//...
You're completely misunderstanding Mr. Richie. He's saying that this:
int n;
void foo()
{
n = 42;
}
requires no extern because the referenced variable n is defined before the function, foo, that uses it.
Were the code like this:
void foo()
{
n = 42;
}
int n;
the compiler now has no idea what you're talking about when using n in the body of foo. There is no n until later, but the compiler has no idea that there ever will be.
You can address this by:
extern int n;
void foo()
{
n = 42;
}
int n;
Now, when compiling foo, the compiler knows there is some int called n ... somewhere. Doesn't know where yet, and frankly doesn't care. Likewise, this will also work:
void foo()
{
extern int n;
n = 42;
}
int n;
That's all he's trying to say. Your code and comments seem to think that by doing this:
void foo()
{
int n;
n = 42;
}
int n;
the n in foo will magically resolve to the outer n. That isn't how the language works. All this does is make the code compile because now the compiler sees an n that fulfills usage for n = 42. It's an automatic variable (lifetime to the { scope } in which it is declared). It has absolutely nothing to do with the int n; outside that scope (but can easily shadow (hide) the name n if you're not careful. That is exactly what is happening in your code.
You seem to be misinterpreting the last part of the statement that "there is no need for an extern declaration in the function" to mean "there is no need for an extern keyword in the function."
What Dennis is saying is that extern int n; in your functions is equivalent to not declaring n at all. extern int n; is not equivalent to int n;, e.g. in main.
I just wanted to know whether it should print 111 as per the author. Now I realized, author is saying "...before its use..." and by "use", he meant "use without (re)definition inside function".
If we define variable again inside function without extern, it will create local variable for function.
(Dont know if I should answer my own question, may be others will correct me if am wrong in this understanding again.)
While making a function atof, I splitted the entire work into two separate translational units:
m.c
#include<stdio.h>
extern fun(char[]); //return type not mentioned on purpose
int main()
{
printf("%d\n",fun("+123.980")); //%f would also display 0.000000
return 0;
}
n.c
#include<ctype.h>
float fun(char c[])
{
float val=0, pow=1;
int i;
int sign;
for(i=0;isspace(c[i]);i++); //SKIPPING WHITESPACE IF ANY
if(c[i]=='+')
sign = 1;
if(c[i]=='-')
sign =-1;
++i;
for(;c[i]!='.';i++)
val = val*10 + (c[i]-'0');
++i;
while(isdigit(c[i]))
{
val = val*10 + (c[i]-'0');
pow=pow*10;
++i;
}
return sign*val/pow;
}
The warning says that the type of function will default to int in this case since every variable/function type at global space without any return type mentioned explicitly defaults to int.
I was expecting the output to be int version of +123.980 i.e 123 only.
But instead it shows 0 (otherwise function works fine). Why?
Implicit int and implicit function declarations are removed from the C language. They are no more. The program is ill-formed. If your compiler accepts it, then you are dealing with a vendor extension — or a compiler for an outdated version of C.
Before these things were removed, the program had undefined behaviour. All editions of the standard require that all declarations of an entity in a program must be compatible, regardless of whether anything in them is implicit or not. Violations of this rule lead to undefined behaviour, with no diagnostic required.
In the program i have not mentioned return type for function fullon but the code still runs and output: "7" is printed. How did this works even when i did not mentioned any return type? i have searched it on this site and i am not able to find any suitable answer.I am still a beginner so i don't have much background of C.
#include<stdio.h>
fullon(int);
int main()
{
int b;
int x = 5 ;
b = fullon(x);
printf("%d" , b);
}
fullon(int y)
{
return y+2;
}
Update 1 :
#include<stdio.h>
fullon(float);
int main()
{
float b;
int x = 5 ;
float f = 3.5;
b = fullon(f);
printf("%f" , b);
}
fullon(float y)
{
return y;
}
Output is 3.000000
Back in the 1980s, pre-standard C (sometimes called K&R C, where K&R refers to the names of Kernighan and Ritchie, who created the language and wrote the first C language manual) allowed function declarations like this one:
noreturntype()
{
//returns something the size of an int
/* do something */
return 456;
}
So even though the function had no return type, it was allowed to return anything that had the same number of bytes as an int on a given implementation. (For instance, if a 16-bit machine had 16-bit integers and 16-bit pointers, it was allowed to return either an int or a pointer in such a function.)
When the C standard was created, these old-style declarations were kept for backwards compatibility with existing programs. (As a matter of fact, even modern compilers tend to accept old-style function declaration along with a warning).
In C, functions have an implied return type of int if it's not specified. This is an ancient quirk and absolutely should not be used; I'm surprised your compiler isn't giving you a warning about it.
Lets say I am maintaining an array of function structures in which I store API information.
This is definition of function structure:
typedef struct function {
void (*func)(long, ...);
char* name;
int argc;
char *argv[];
} function;
function api_list[N]
I would maintain a list of such structures.
Now given any function, I want to write a function Register(api_list, fp)
which adds one such structure initialized with details of function fp.
int fp(int a, int b) {
return a+b;
}
Register(api_list, fp);
How to do it in C?
I believe you will need to either parse the C function declarations yourself or find some other code to do it. I looked around a bit and there's code for this in the Ruby FFI, PerlXS and other script binding generators like SWIG. I also saw the XML plugin to GCC which generates XML describing the program.
If you look up C's BNF or EBNF definitions and know a bit of parsing theory, figuring out C functions is not hard. C++ is a whole other ball o' wax.
Note: I think I misunderstood. The following is for calling C functions with unknown number and types of arguments. Not for finding out what the function signature already looks like.
Look at the FFI (Foreign Function Interface) library which can be found at Sourceware:
https://sourceware.org/libffi/
This is packaged with many Linux systems already because it is heavily used by interpreted languages that need to call C functions.
Now given any function, I want to write a function Register(api_list, fp) which adds one such structure initialized with details of function fp.
There is no way to do this in Standard C. The main reason is you need keep track of original definition of an function to call it via such structure. You actually could store every function pointer as struct member:
void (*func)()
that is fine, but any attempt to call such function when type is not compatible (both parameters and return type are not the same) with original definition will invoke undefined behaviour. This means, that you would need to cast it properly for every call:
((int (*)(int, int)) api_list[0])(1, 2);
You may use GCC extensions typeof, but this method requires writing function's name (here fp) explicitely:
int result = ( (typeof(fp)*) api_list[0].func)(1, 2);
Even if you have stored somehow character string "fp" inside name member, there is no way to "connect" it with typeof, since it does not take string literals (well it takes, but not in the way you want) and in general there is no way to have it "destringized" as fp token.
Here is an illustration of above concepts:
#include <stdio.h>
typedef void (*GENERIC_FUNC_PTR)();
typedef struct function
{
GENERIC_FUNC_PTR func;
} function;
void Register(function *api_list, GENERIC_FUNC_PTR func)
{
api_list->func = func;
}
int add(int a, int b)
{
return a + b;
}
void print_message(void)
{
printf("%s\n", __func__);
}
int main(void)
{
function api_list[10];
Register(api_list, (GENERIC_FUNC_PTR) add);
Register(api_list + 1, (GENERIC_FUNC_PTR) print_message);
printf("%d\n", ( (typeof(add)*) api_list[0].func)(1, 2));
( (typeof(print_message)*) api_list[1].func)();
return 0;
}