VS2010 with extern keyword - c++

I have the following two files:
foo.h
bar.cpp
In foo.h I decleare a variable extern.
Now, I would like to use the same variable in bar.cpp (after including foo.h).
Under VS2008 and VS2010 I get unresolved external symbol errors, while under Ubuntu with gcc the compilation is successfull.
(Namely, I'm trying to compile the following source code:http://www.fromdual.com/using-mysql-user-defined-functions-udf; foo.h refers to srv0srv.h and bar.cpp refers to the source code. All includes are in place, compilation is a success, linking falls)
What might the problem be?

The extern keyword indicates to the compiler that the variable following it is already declared somewhere else. It does not actually allocate space for the variable. If you want to create a global variable which you can use by including a header file (which is generally a bad idea, by the way), you can do it in the following manner.
In foo.h:
extern int myVar;
in foo.cpp:
int myVar;
myVar is now located in foo.cpp, but the extern statement in foo.h allows code in other files (such as bar.cpp) to access it by including foo.h.

When you use extern to declare a variable(a global variable in other source objects or files), you actually tell compiler to look for the variable's definition somewhere else. In this case, you need to provide another source file that defines int myVar.

Your variable has to have a reference somewhere in one of the source files. By the extern keyword you are only telling that "there is a variable" but linker has to know the location of it. While you are compiling the source, it will create references for variables etc. Linker will link according to these references. If you do not actually create a reference to a variable linker will not be able to find the reference, so it will give error. If you use extern you are saying that do not create a reference to this variable or any other thing here. But there has to be a reference to it at somewhere else.

The problem was, that the afformentioned symbol has to be exported (via dllspec) from the dll, to be visible from outside. Only the extern keyword did not allowed it to be seen from outside.

Related

One Definition Rule - compilation

I am trying to understand ODR.
I created one file pr1.cpp like this:
struct S{
int a;
};
a second file pr2.cpp like this
struct S {
char a;
};
and a main file like this :
#include <iostream>
int main() {
return 0;
}
I am compiling using terminal with the command :
g++ -Wall -Wextra pr1.cpp pr2.cpp main.cpp -o mypr
The compiler does not find any kind of error BUT there are two declarations of the type "S"...I am not understanding what is really happening..I thought to get an error after the "linkage" phase because of the ODR violation..
I can get the error only editing the main.cpp file adding :
#include "pr1.cpp"
#include "pr2.cpp"
Can anyone exmplain me what is happening?
Unless you include both definitions in the same file, there is no problem. This is because the compiler operates on a single translation unit which is usually a .cpp file. Everything you #include in this file is also part of the translation unit because the preprocessor basically copies and pastes the contents of all included files.
What happens is that the compiler will create and object file (.obj usually) for each translation unit and then the linker will create a single executable (or .dll etc) by linking all the object files and the libraries the project depends on. In your case the compiler encountered each struct in a different translation unit so it doesn't see a problem. When you include both files, the two definitions now find themselves in the same translation unit and the compiler throws an error because it cannot resolve the ambiguity if an S is used in this translation unit (even though you don't have to use one for the program to be ill-formed).
As a side-note, do not include .cpp files in other .cpp files. I'm sure you can find a lot on how to organize your code in header and source files and it doesn't directly answer the question so I won't expand on it.
EDIT: I neglected to say why you didn't get a linker error. Some comments have pointed out that this is undefined behavior which means that even though your linker should probably complain it doesn't actually have to. In your case you have one .obj file for each struct and a main.obj. None of these references the other so the linker does not see any references that it needs to resolve and it probably doesn't bother checking for ambiguous symbols.
I assume most linkers would throw an error if you declared struct S; and tried to use a S* or S& (an actual S would require definition inside the same translation unit). That is because the linker would need to resolve that symbol and it would find two matching definitions. Given that this is undefined, though, a standard-compliant linker could just pick one and silently link your program into something nonsensical because you meant to use the other. This can be especially dangerous for structs that get passed around from one .cpp to the other as the definition needs to be consistent. It might also be a problem when identically named structs/classes are passed through library boundaries. Always avoid duplicating names for these reasons.

Defining an extern variable in the same header file

I am wondering if it is possible to both declare and define an extern variable in the same header file. I need the variable to be referenced across multiple files, and while I realize there are better ways to achieve this, using extern is the only option in this case. So is it possible to do:
// in main.h
extern int foo;
int foo;
etc...
And then any file which includes main.h will have access to foo? Many examples reference defining the extern'd variable in a separate cpp file, but I'm just wondering if the way I suggested will cause problems across the rest of the project.
If you put a definition in a header file, you will end up with multiple definitions when multiple source files are involved.
For example, suppose both main.c and other.c include foo.h. When you compile each of these files you'll get main.o and other.o, both of which have a definition of int foo. If you then attempt to link main.o and other.o into a single executable, you'll get a linker error stating that int foo was defined twice.
To do this properly, you declare your variable in the header file as extern int foo. Then, in one (and only one) source file you define the variable with int foo.
Real definitions (not extern) should not be in a header file.
If you want to have one global variable available from different cpp, you should make two things: definition in one cpp and extern declaration in h.
E.g.:
// global.h
extern int foo;
and
// global.cpp
int foo;
Then in any file where foo is needed:
#include "global.h"
And, of course, global.cpp have to be part of project (compiled with other files)
What you are doing is perfectly legal in C++ only if there aren't multiple files which are defining the same variable.
The variable or function may be defined in another source file, or
later in the same file. Declarations of variables and functions at
file scope are external by default.
Normally we extern a global variable declared in some other file.
This is as good as a global variable initialized to 0.

using global variable in dll and exe

i have an global variable in an common header file. Eg
commonHeader.h
int commonInt = 0;
i have 3 dll projects in which i want to use it , so i include above header, but it give me error symbol defined multiple times , #pragma once also did't work.
if i make above variable extern , and define it in my exe i get linker errors in my dll.
all my dll need above header.
one of my dll need other 2 dll's header file (probably making multiple include of syombol)
how i can resolve above issue , i want only one variable across dll and exe.
i am using VS 2010 prof on windows 7.
thanks in advance.
You're violating the One Definition Rule (§ 3.2) by having that global variable definition in a header file. Instead you were correct to only declare it in a header file with extern and then have the definition in a single implementation file.
But in order to have this work with dlls you also have to declare it as exported by the exe and imported by the dlls with __declspec(dllexport) and __declspec(dllimport), using appropriate macros to choose the right __declspec depending on whether you're compiling the exe or the dlls.
You should only declare globals in a header. They should be defined in an implementation (source) file.
In your header you should have:
// commonHeader.h
extern int commonInt; // global *declaration*
and then in one of your implementation files you should have:
// some_file.cpp
int commonInt = 0; // global *definition* (and initialisation)
Of course global variables should be avoided wherever reasonably possible - excessive use of globals is a "code smell", but sometimes it can not be avoided.

Global variables multiple declaration

I am including a .h file with a global boost signal in a the header file of a class which is, in turn included in the main function's file. The linker says the signal is declare multiple times. The signal declaration is wrapped in the #ifndef, #define and #endif block typical of C/C++ header files (used to avoid multiple declaration).
I am using Eclipse with gcc.
#ifndef SIG_HEADER
#define SIG_HEADER
#include <boost/signal.hpp>
boost::signal0 <void> signal1;
#endif
what am I doing wrong?
You're getting a linker error, not a compiler error. So, preprocessor directives won't help you here.
What you need to do is define the variable inside the source file (as opposed to the header file), and use an extern declaration in the header file.
Your linker is correct. Each time you include this header the symbol signal1 gets defined, resulting in a multiple definition error.
To your rescue comes the extern keyword, which will tell the compiler that this is an object that will be accessed by the entire program and requires external linkage. You will then have to give the compiler a definition of the variable somewhere else, like in the cpp file for this header.
This question offers some more information about external linkage.

Is it required to add 'extern C' in source file also?

I found some code recently where extern "C" was added in source file also for functions. They were also added in the header files where they were declared.
I was under the assumption that adding 'extern "C" in header files was sufficient.
Where should extern "C" blocks be added?
UPDATE:
Suppose I am compiling my C code using a CPP compiler and have added extern "C" guards for all the functions in header files (i.e. all my functions have their prototypes in headers), but in source files I have not added the same. Will this cause a problem?
Since you mean
extern "C" { ... }
style guards, these declare some functions to be of "C" linkage, rather than "C++" linkage (which typically has a bunch of extra name decoration to support things like overloaded functions).
The purpose, of course, is to allow C++ code to interface with C code, which is usually in a library. If the library's headers weren't written with C++ in mind, then they won't include the extern "C" guards for C++.
A C header written with C++ in mind will include something along the lines of
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif
to make sure C++ programs see the correct linkage. However, not all libraries were written with C++ in mind, so sometimes you have to do
extern "C" {
#include "myclibrary.h"
}
to get the linkage correct. If the header file is provided by someone else then it's not good practice to change it (because then you can't update it easily), so it's better to wrap the header file with your own guard (possibly in your own header file).
extern "C" isn't (AFAIK) ANSI C, so can't be included in normal C code without the preprocessor guards.
In response to your edit:
If you are using a C++ compiler, and you declare a function as extern "C" in the header file, you do not need to also declare that function as extern "C" in the implementation file. From section 7.5 of the C++ standard (emphasis mine):
If two declarations of the same
function or object specify different
linkage-specifications (that is, the
linkage-specifications of these
declarations specify different
string-literals), the program is
ill-formed if the declarations appear
in the same translation unit, and the
one definition rule
applies if the declarations appear in
different translation units. Except
for functions with C++ linkage, a
function declaration without a linkage
specification shall not precede the
first linkage specification for that
function. A function can be declared
without a linkage specification after
an explicit linkage specification has
been seen; the linkage explicitly
specified in the earlier declaration
is not affected by such a function
declaration.
I'm not convinced it's good practice though, since there's the potential for the linkage specifications to diverge by accident (if, for example, the header file containing the linkage specification isn't included in the implementing file). I think it's better to be explicit in the implementation file.
They only need to go in anything that is included by other source files.
With some idioms you'll find people including source files.
They should be added to all files, that get included in other files.
Normally, one doesn't include source files.
Apologia
The question has changed to be much clearer what it was asking about. This answer addressed the original question, when it was at least debatable whether it was discussing guards against multiple inclusion in header files - which is what my answer addresses. Clearly, if the question had been as clear then as it is now, I would not have submitted this answer.
Original answer
No, it is not necessary to include the guards in the C code too.
If the header file 'header.h' says:
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
...
#endif
Then it is perfectly safe for a source file 'source.c' to say:
#include "header.h"
It is also safe for other headers to include 'header.h'.
However, people note that opening a header file and reading it takes time, which slows up a compilation, so sometimes people do things like:
#ifndef HEADER_H_INCLUDED
#include "header.h"
#endif
This means that if some other header included in 'source.c' has already included 'header.h', then the '#include' is not re-processed. (Or, if 'header.h' has already been included directly in 'source.c', though that's a silly buglet.)
So, when encountered, it is likely to be an attempt to optimize the compilation performance. It is far from clear that it buys you much; modern C preprocessors are fairly intelligent about the issue and will avoid re-including the file if they can. And there's always a risk that the test in 'source.c' has a typo (#ifndef HEARER_H_INCLUDED, perhaps) in which case the test slows the compilation because the preprocessor tests the irrelevant condition and then proceeds to include 'header.h' after all. It is 'safe'; the header is itself protected-- or should be.
If you see the code in 'source.c' also doing '#define HEADER_H_INCLUDED', then there are problems. The #define has to be either before or after the #include, and neither is good as a general technique.
If 'source.c' does '#define HEADER_H_INCLUDED' before including 'header.h', then if the guard appears in 'header.h', the contents of the header will not be included. If the guard does not appear in 'header.h', then things work OK.
If 'source.c' does '#define HEADER_H_INCLUDED' after including 'header.h', then if the guard appears in 'header.h', we get a benign redefinition of HEADER_H_INCLUDED. If 'header.h' does not contain the guard but does include a file which includes 'header.h', you are not protected from multiple inclusion after all.
Note that body of the header appears after the '#define HEADER_H_INCLUDED'. This is again protection if nested includes include 'header.h'.
You mean the 'extern c' preprocessors? They have to be on the function definition as well as that affects how the function call is stored in the compiled binary. Its only really needed if you are linking compiled c++ together with c which is compiled as C (as opposed to c in a .cpp file).
The "C" guards have two purposes:
When your code is compiled, the functions will be exported in a way that will allow a non C++ compiler/linker to use them (no C++ name mangling etc.)
When a C++ compiler uses your header files, it will know that it should bind the symbols in the C way which in turn will make sure that the resulting program will link successfully. They don't carry a meaning for a non C++ compiler but since the symbols were generated in C-style in (1) this is the desired effect.
Since you include the header with the "C" guards also in your implementation file, the information on how the symbols should be created at compile time is available to the compiler and the compiler will create the symbols in a way that can be used by a non C++ compiler. Consequently you only need to specify extern "C" in your header file as long as the header file is also included by the implementation file.
it is not required for extern to be used in source files, if they are used in the header file and that file is included by the rest of the source files.
As far as I remember the standard, all function declarations are considered as "extern" by default, so there is no need to specify it explicitly. That doesn't make this keyword useless since it can also be used with variables (and it that case - it's the only solution to solve linkage problems). But with the functions - yes, it's optional.
A little more verbose answer is that it allows you to use variables compiled in another source code file, but doesn't reserve memory for the variable. So, to utilise extern, you have to have a source code file or a library unit that contains memory space for the variable on the top level (not within functions). Now, you can refer to that variable by defining an extern variable of the same name in your other source code files.
In general, the use of extern definition should be avoided. They lead easily to unmanagable code and errors that hard to locate. Of course, there are examples where other solutions would be impractical, but they are rare. For example, stdin and stdout are macros that are mapped to an extern array variable of type FILE* in stdin.h; memory space for this array is in a standard C-library unit.
We had always only added extern "C" to the header definitions, but this allows the C++ code to implement the function with a different signature via overloading without errors and yet it doesn't mangle the symbol definition so at link times it uses this mismatching function.
If the header and the definition both have extern "C" then a mismatched signature generates an error with Visual Studio 2017 and with g++ 5.4.
This following code compiles without an error for Visual Studio 2017 and g++ 5.4
extern "C" {
int test(float a, int b);
}
int test(int b)
{
return b;
}
It seems that gcc mangles the symbol name in this case but Visual Studio 2017 does not.
However including the extern "C" with the definition catches the mismatch at compile time.
extern "C" {
int test(float a, int b);
}
extern "C" int test(int b)
{
return b;
}
gives the following error on g++:
g++ -c -o test.o test.cpp
test.cpp: In function ‘int test(int)’:
test.cpp:4:26: error: conflicting declaration of C function ‘int test(int)’
extern "C" int test(int b)
^
test.cpp:2:9: note: previous declaration ‘int test(float, int)’
int test(float a, int b);
or with cl
cl /c test.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27042 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(4): error C2733: 'test': second C linkage of overloaded function not allowed
test.cpp(2): note: see declaration of 'test'