Error when declaring global variable in objective c++? - static

I get the error Command/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-g++-4.2 failed with exit code 1 whenever I put a global variable id theScene in a .mm file. It works with a .m file but I need .mm for box2d implementation later on. Also, I think the real error resides here:
ld: duplicate symbol _theScene in /Users/sgupta100/Documents/TheifGame/build/TheifGame.build/Release-iphonesimulator/TheifGame.build/Objects-normal/i386/HelloWorldScene.o and /Users/sgupta100/Documents/TheifGame/build/TheifGame.build/Release-iphonesimulator/TheifGame.build/Objects-normal/i386/TheifGameAppDelegate.o
I do not know what this really means so can someone explain?

Is this variable declared in a header somewhere? If so, does the declaration use the extern keyword? If it doesn't, the compiler will emit a symbol for each compilation unit (.m, .mm, .c, .cpp, etc.) that #includes the header.
If the header isn't a problem, something in both your "HelloWorldScene" and "TheifGameAppDelegate" compilations unit is producing a theScene symbol. Either the variable is defined in both, or something else, such as a function, happens to have the same name.
Without posting your code or other details, there's no more I can tell you about this issue.
Update: the correct way to use global variables across multiple files is to declare the variable as extern in a header (conditionally use extern "C" when compiling with (Objective-)C++ and the variable also needs to be accessible from (Objective-)C. Then define it exactly once in a .m, .mm, .c or .cpp file without the extern and possibly with an initialiser. The header must of course be included by all files that require access to the variable.

Related

weird static function behaviour

i am looking at static functions, i know they have a scope limited to the file they are declared in. For clarification i use code blocks with GCC. If i declare the function in a ..c file and include it in my main.c file, the function can be accessed (but the compiler will complain if a non static function is defined, as i have multiple definitions). However if i have a c file with some static function and another non-static function, then the static function is not accessible and the non-static function is accessible. This to me is a rather weird. I know that the #include directive copies the contents of the to-be-included file in to the file where the include directive is declared. But then why can i access the non-static function without including the .c file in the main.c file?
Any suggestions on where i could read up on this topic? I am thinking it has something to do with linking, but i may be wrong.
When a function is declared without static, it has external linkage.1 This means that, when the program is linked2, the same name in different translation units3 can be made to refer to the same thing.
When you define a function in one source file, say int square(int x) { return x*x; }, compiling that source file produces an object file that contains information saying “The function foo is defined here.” When you declare a function in another source file and use that function, such as int square(int x); … b = square(a);, compiling that source file produces an object file that contains information saying “The function foo is used here.” When the linker or program loader processes these object files, it modifies the place where foo is used to refer to the place where foo is defined.
If you use a function without declaring it in that translation unit, your compiler might provide a default declaration for the function, as if it had been declared to return int with no information about its parameters. This behavior is a legacy of old versions of C. Quite likely your compiler issues a warning such as “implicit declaration of function” for this. You should not ignore this warning. When it appears, find the code causing the warning and fix it—either correct the typing of a misspelled function name or insert a declaration for the function.
When using GCC or Clang, you should use the switch -Werror to elevate warnings to errors, so that the compiler will not compile programs that cause warning messages. While this may at first make it more of a nuisance to get your programs compiled, it causes you to fix errors early and to learn to program correctly.
Footnotes
1 With static, an identifier for a function has internal linkage. The rules for identifiers for objects (which you may think of as variables) are more complicated, and they can also have no linkage.
2 In practice, each compilation produces an object module. Linking combines object modules to make an executable program or, in complicated builds, new object modules.
3 A translation unit is the source file being compiled including all the files it includes with #include statements.
So I found a decent answer to your question in a different stackoverflow question, but before I get to that I want to explain why including .c files is bad practice, and shouldn't be done:
As you pointed out, #include copies the content of the file. This means that you can't include the .c file more than once, since you would be creating >1 instance of the same function (of the same name).
If you try to create a universal .c file, say, math.c, you can't create any other .c files that use any of its functions, since you can only include it once, and thats reserved for your main.c file. This severely limits the usefulness of every function in your .c files
instead, you should only ever include header files (.h). You declare your functions in your .h file, define in your .c file.
Whatever functions you declare in your .h file, you can then use in any other files where said .h file is included, without causing compiler errors
I get that this is confusing, but here's examples from another stackoverflow thread
here's a further better document explaining how header files (.h) work
Why can you access non-static function despite not including the .c file?
this should not be possible generally in c if you're not explicitly including said .c file. If I were to do that I would get an "implicit declaration" function, because the compiler doesn't recognize the functions, as they've not been declared previously.
relevant stack overflow answer
long story short, declaring a function static in a .c file means that its scope is limited only to said .c file, you can't call it anywhere else

Variable defined but not used message in kernel module

In my Kernel module, I have two very short C source files (the main file and a daq.c and daq.h file). The header file contains a number of variables and functions. When I compile the functions normally, by declaring the variable in the daq.h file:
volatile uint32_t *gpio;
I receive the following error:
error In function `.LANCHOR1':
daq.c:(.bss+0x50): multiple definition of `gpio'
This error is only solved by declaring the variable as static, as follows:
static volatile uint32_t *gpio;
The kernel module works fine but in this case I receive the following warning as a static declaration creates a separated copy on every file in which it is included:
warning: ‘gpio’ defined but not used [-Wunused-variable]: static volatile uint32_t *gpio;
I've tried to declare it extern or just simply declaring the variable as uint32_t *gpio instead of declaring it static but then I get a:
WARNING: "gpio" undefined!
followed by an "out-of-tree definition" message in the dmesg log when the module is inserted (and the module is not loaded).
So, in this case, how is the best way to proceed in order to declare the variable? Is it correct to declare it as:
static volatile uint32_t *gpio;
and just omit the "defined but not used" warning given by the compiler? I don't think just "omitting" the warnings is a good practice, especially when it comes to kernel modules.
Thanks in advance.
Your question is not very clear because a full context is missing; but anyway I think some advice can be given.
First, your sources will be used together with other files; those files define things you have to be aware of, otherwise things like multiple definition of 'gpio' come out. In this case (gpio), you must decide if you want to interact with the "other" gpio variable - if not, you must use another name (it is not mandatory, but it is better).
Second, you must understand how the C compiler works, especially if you interface with the kernel, which adds some mechanisms. In general, you don't want to define variables in a header (.h) file; instead, you do declare them, together with data types, macros, and function prototypes. In the source files (.c) you #include headers in order to use the declarations found in them.
Variables are defined in .c files, and made available to other modules through header files, if this is wanted. Otherwise, make them static and do not mention them in the header.
The difference between declaration and definition is this: a declaration tells the compiler "you will encounter (perhaps) this name, somewhere, which has the following properties"; a definition instead means "I create this name, with these properties, and this thing is exactly here.".
When more than a single piece of software are used together, often happens that one piece does something needed in another one... declaration are the way to let these pieces work together.
Hope this helps a little.

Extern array of function pointers in C on a fixed memory address

I'm working on a embedded application where I need to declare an array of function pointers on a fixed memory address and then use it in different .c files. What I came up with is this:
typedef void(__irq __arm * p_intr_handler_t)(void);
p_intr_handler_t * IntTable = (p_intr_handler_t *)&VIM_RAM_BASE;
p_intr_handler_t IntTable[95];
VIM_RAM_BASE is the address. I delcare this in main.f file and I need to use it in various .c files, so I declared it like this:
extern p_intr_handler_t IntTable[95];
But whilst trying to compile I get an error message:
"declaration is incompatible with "p_intr_handler_t *IntTable" (declared at line 3)"
that message goes for both the normal and the extern declaration.
Any ideas what's wrong?
Thanks
Depending on what you're trying to do, it may make more sense to do this with the linker rather than the compiler. In that case you just declare the symbol as extern in the C file (with no definition at all), and tell the linker where it is. So your header would contain:
extern p_intr_handler_t IntTable[95];
and then you'd add a link-time option (GNU gcc/ld syntax here -- other linkers are different)
-Wl,--defsym=_IntTable=0x8000000
where you set the address to whatever you like. Check out the documentation for your linker to see what the equivalent option is.
Why are you redeclaring IntTable with a different type?
Just jeep the first definition in a single .c, and create an extern for it in a .h to be included in the other .c, like this:
extern p_intr_handler_t * IntTable;
Obviously this works only if VIM_RAM_BASE is already somehow reserved for your data (i.e. the compiler won't try to put there other data), otherwise you should check out your compiler's documentation to see if there's a way to tell it to put a variable at a specific place in memory.
You've defined IntTable twice, shouldn't you rename that to something else?

Two variables with same name and type, in two different .c files, compile with gcc

Here's the deal. I've had two identical global variables in two different .c files, they weren't declared as extern. So each .c file should have seen its own variable, right?
But I have gotten some really strange behaviour, as if one file was reading the other files variable (after linking them together). Adding 'static' qualifier to both variables definitions seemed to fix this issue.
So what I'm actually wondering is, what exactly happened there without the 'static' qualifier?
So each .c file should have seen its own variable, right?
Wrong. In C, omitting static from a declaration means implicit extern linkage.
From C In a Nutshell:
The compiler treats function declarations without a storage class
specifier as if they included the specifier extern. Similarly, any
object identifiers that you declare outside all functions and without
a storage class specifier have external linkage.
ALWAYS initialize global variable, then compiler will not consider its linkage automatically as extern. Compiler will throw error during compilation.
This will help to avoid random problems in big code base ,because our code may use somebody else declared variable that has some random value (in our logic perspective)
output file is generated by making object file of individually file and then linking them together by linker. Now when you have identical variable in two different file then individual file will compile with no error but at time of linking linker will get two definition of variable and generate an error. But In the case of static scope of both variable limited for the file so, every things works fine.
I hope you will find this useful.
As far as I know, when you do not specify neither static nor extern then it's up to the compiler to choose. And gcc in this case goes for extern, thus you have to specify static in your case.
I had the same problem, a few years ago :-)

How to deal with duplicated function name within C?

I have a little project in which I named two same name function in two different source file, but while I building the project, the compiler failed with 'func_name already defined in filename.obj'.
Why could not I have two functions with the same name in two different source files? I thought the function should be local to the source file only if when we declared it in the header file will it become global.
And except for changing the filename, are there any other elegant solution to duplicated function name in the C programming language?
In C, a function has global scope by default. To restrict its scope, use the static keyword to make it private to a the module.
The role of the header file is just to publicize the function along with its signature to other modules.
All global names must (with some caveats) be unique. This makes sense because that name is what is used by the linker to connect a function call to implementation of the function itself.
Names with static and local scope need only be unique within their scope.
Whether some thing is declared in header file or in source file makes absolutely no difference for the compiler. In fact, the compiler proper knows absolutely nothing about any "header files", since header files are embedded into source files by so called preprocessor, which does its work before the compiler proper. By the time the source files (with embedded header files) get to the actual compiler, there's no way to tell what was there originally and what was inserted from header files. The source file with all the header files embedded into it is called translation unit. I.e. the compiler proper works with translation units, not with some "source" or "header" files.
In C language all objects and functions declared at file scope have external linkage by default, which means that they are global, unique for the entire program. So, you thought incorrectly. Functions are not local to one source file only.
If you want to make a function (or an object) local to a single translation unit, you have to take some explicit steps. You have to declare it as static. Declaring it as static will give it internal linkage, which essentially means that it becomes internal to its translation unit.
Declaring your functions static will only work if both of them really have to be local to their own translation units. If this is not the case, i.e. if at least one of the functions should be a globally accessible (linkable) function, then you have no other choice but to rename one of functions.
Why could not I have two function with the same name in two differenct source file?
Because the linker needs to know which is meant when you reference it.
Imagine that a.h and b.h both declare my_function(). The compiler generates code for both. Now, imagine that c.c calls my_function() - how does the linker know which of the two versions of the function should be called?
Declare the function static to make it local to the file. In C, every identifier name must be unique.
The elegant solution is namespaces introduced in C++. The solution, if there are few calls to func_name is take one, rename it and recompile.
Something hackerous but quick solution might be this:
//In one of the two source files and any file that calls it
//if your functions is something like this
//void func_name(int) { ... }
//Add the following line
#define func_name SOME_UNIQUE_FUNC_NAME

Resources