linkage
What exactly does putting extern "C"
into C++ code do?
For example:
extern "C" {
void foo();
}
Doesn't std::piecewise_construct cause a ODR violation?
std::piecewise_construct
, defined in <utility>, has internal linkage since it is declared constexpr
. I wonder if use of std::piecewise_construct
in a header can violate ODR. For example:
#include <utility>
#include <tuple>
struct point
{
point(int x, int y)
: x(x), y(y)
{}
int x, y;
};
inline std::pair<point, point> f(int x1, int y1, int x2, int y2)
{
return {
std::piecewise_construct,
std::forward_as_tuple(x1, y1), std::forward_as_tuple(x2, y2)
};
}
#include "a.hpp"
#include "a.hpp"
The std::piecewise_construct
in f
in TU 1 refers to a different object than that in f
in TU 2. I suspect f
violates ODR.
N3290 (probably ISO/IEC 14882:2011 also) says the following case is an exception of ODR, in 3.2/5:
a name can refer to a const object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (5.19), and the value (but not the address) of the object is used, and the object has the same value in all definitions of D;
f
satisfies almost all the requirements, but "the value (but not the address) of the object is used" seems ambiguous to me. It's true that std::piecewise_construct_t
has no state, but a call of the piecewise constructor of std::pair
involves a call of the implicit-declared copy constructor of std::piecewise_construct_t
, whose argument is const std::piecewise_construct_t &
. The address is "used", isn't it?
I'm very puzzled.
Reference: http://lists.boost.org/Archives/boost/2007/06/123353.php
Why do inline functions have external linkage by default?The standard says that given a declaration of
inline void foo();
that foo
is an inline function with external linkage (because by default all function declarations have external linkage). This strikes me as odd. because the one definition rule section 3.2 (in both C++03 and C++11) say:
3 ... An inline function shall be defined in every translation unit in which it is used.
5 There can be more than one definition of a[n] ... inline function with external linkage (7.1.2) ... Given such an entity named D defined in more than one translation unit ... each definition of D shall consist of the same sequence of tokens
This means that an inline function might as well have internal linkage, because use of the function in any way through external linkage (that is, across translation units) would be to invoke undefined behavior (by paragraph 3), and that the content of the inline function in all translation units needs to be the same.
Is there a backwards compatability or specific toolchain reason for this rule?
Is it legal C++ to declare main as extern "C"?Being a low-level programmer, I often work with the module startup code for executables, so I understand pretty well how code like "crt0" work. When writing C++ code, I've generally declared main
as extern "C"
to match what the C startup code is going to do to call main
. I thus usually use this declaration for main
(and wmain
if specifically targeting Windows):
extern "C" int main(int argv, const char *const *argv)
extern "C" int __cdecl wmain(int argv, const wchar_t *const *argv)
Is it legal to use extern "C"
on main
? Also, is const char *const *
legal for argv's type as opposed to char *[]
?
In C++, putting a function or a variable in an anonymous namespace makes its linkage internal, i. e. the same as declaring it static
on a file-level, but idiomatic C++.
What about an anonymous namespace within a normal namespace? Does it still guarantee internal linkage?
// foo.cpp
void func1() {
// external linkage
}
static void func2() {
// internal linkage
}
namespace {
void func3() {
// internal linkage
}
}
namespace ns1 {
void func4() {
// external linkage
}
namespace {
void func3() {
// still internal linkage?
}
}
}
static vs extern "C"/"C++"
What is the difference between a static member function and an extern "C" linkage function ? For instance, when using "makecontext" in C++, I need to pass a pointer to function. Google recommends using extern "C" linkage for it, because "makecontext" is C. But I found out that using static works as well. Am I just lucky or...
class X {
public:
static void proxy(int i) {}
}
makecontext(..., (void (*)(void)) X::proxy, ...);
vs
extern "C" void proxy(int i) {}
makecontext(..., (void (*)(void)) proxy, ...);
EDIT: Can you show a compiler or architecture where the static member version does not work (and it's not a bug in the compiler) ?
What does mean for a name or type to have a certain language linkage?According to (c) ANSI ISO/IEC 14882:2003, page 127:
Linkage specifications nest. When linkage specifications nest, the innermost one determines the language. A linkage specification does not establish a scope. A linkage-specification shall occur only in namespace scope (3.3). In a linkage-specification, the specified language linkage applies to the function types of all function declarators, function names, and variable names introduced by the declaration(s).
extern "C" void f1(void(*pf)(int));
// the name f1 and its function type have C language
// linkage; pf is a pointer to a C function
extern "C" typedef void FUNC();
FUNC f2;
// the name f2 has C++ language linkage and the
// function's type has C language linkage
extern "C" FUNC f3;
// the name of function f3 and the function's type
// have C language linkage
void (*pf2)(FUNC*);
// the name of the variable pf2 has C++ linkage and
// the type of pf2 is pointer to C++ function that
// takes one parameter of type pointer to C function
What does all this mean? For example, what linkage does the f2()
function have, C or C++ language linkage?
As pointed out by @Johannes Schaub, there is no real explanation of what this means in the Standard so it can be interpreted differently in different compilers.
Please explain the differences in the object file:
In the C++11 standard, what is the difference between constexpr
and static constexpr
global variables when defined in a header? More specifically, when multiple translation units include the same header, which declaration (if any) is guaranteed to define the same variable across the translation units?
e.g.,
cexpr.h:
#ifndef CEXPR_H
#define CEXPR_H
constexpr int cint = 1;
static constexpr int scint = 1;
#endif
a.cpp:
#include "cexpr.h"
b.cpp:
#include "cexpr.h"
Why does the extern āCā group C++ class (not header) here?
I was searching SVM libraries and encountered BudgetedSVM.
In the source code, I found an unusual usage, just like this:
#sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
//no header included or namespace declared here
#ifdef __cplusplus
extern "C" {
#endif
//no header included or namespace declared too
class Sample: public Parent
{
public:
Sample();
~Sample();
type0 fun(type1 val1, type2 val2);
...
};
#ifdef __cplusplus
}
#endif
#endif // SAMPLE_H
As seen, no extra header or namespace is needed in the header, which all are in the cpp file.
Here are my thoughts:
Why does extern "C"
, which usually is used for C interfaces, group the C++ class? Is the usage in this way good for something?
Even if type0
, type1
and type2
appeared, their own headers are not included here, but in the cpp file (e.g. sample.h). When I call the class Sample
, however, I have to include these headers (e.g. type0.h
, type1.h
, type2.h
), which seems inconvenient.
Why the following doesn't compile?
...
extern int i;
static int i;
...
but if you reverse the order, it compiles fine.
...
static int i;
extern int i;
...
What is going on here?
c & c++ default global variable linkage, multiple declaration & definition problemFor example:
code1.c / .cpp
int a;
// ... and so on
code2.c / .cpp
int a;
int main(void) {
return 0;
}
go to compile:
$gcc code1.c code2.c # this is fine
$
$g++ code1.cpp code2.cpp # this is dead
/tmp/ccLY66HQ.o:(.bss+0x0): multiple definition of `a'
/tmp/ccnIOmPC.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status
Is there any global variable linkage difference between C & C++?
constexpr global constants in a header file and odrUnfortunately, I am somewhat confused about constexpr
, global constants declared in header files, and the odr.
In short: Can we conclude from here
https://isocpp.org/files/papers/n4147.pdf
that
constexpr MyClass const MyClassObj () { return MyClass {}; }
constexpr char const * Hello () { return "Hello"; }
is preferable over
constexpr MyClass const kMyClassObj = MyClass {};
constexpr char const * kHello = "Hello";
for defining globals in a header file if I want to "just use" those globally declared/defined entities and do not want to think about how I use them?
Why can't templates be within extern "C" blocks?This is a follow-up question to an answer to Is it possible to typedef a pointer-to-extern-āCā-function type within a template?
This code fails to compile with g++
, Visual C/C++, and Comeau C/C++ with basically the same error message:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
template <typename return_t_, typename arg1_t_>
struct test {
static void foo(return_t_ (*)(arg1_t_)) { }
};
}
int main()
{
test<int, int>::foo(&do_stuff);
return EXIT_SUCCESS;
}
g++ says "error: template with C linkage", Visual C/C++ emits compiler error C2894, and Comeau C/C++ says "error: this declaration may not have extern "C" linkage".
The thing is, all are happy with:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
struct test {
static void foo(int (*)(int)) { }
};
}
int main()
{
test::foo(&do_stuff);
return EXIT_SUCCESS;
}
Section 7.5, Linkage specifications, of the C++ Standard states:
A C language linkage is ignored for the names of class members and the member function type of class member functions.
And it even gives the example:
extern "C" {
class X {
void mf(); // the name of the function mf and the member
// function's type have C++ language linkage
void mf2(void(*)()); // the name of the function mf2 has C++ language
// linkage; the parameter has type pointer to C function
};
}
If templates were allowed in extern "C" blocks, then the member functions of the instantiations would have C++ linkage.
Why, then, does chapter 14, Templates, of the C++98 Standard state:
A template name may have linkage (3.5). A template, a template explicit specialization (14.7.3), and a class template partial specialization shall not have C linkage.
What does it mean that a template "may" have linkage? What is template linkage?
Why is it explicitly forbidden to have a template with C linkage, when a class is okay, and all member functions of instantiations of the template (the default constructor, destructor, and assignment operator overload) would have C++ linkage?
About inconsistent dll linkageHow can I remove this link warning? You can see code segment that causes this warning.
static AFX_EXTENSION_MODULE GuiCtrlsDLL = { NULL, NULL };
//bla bla
// Exported DLL initialization is run in context of running application
extern "C" void WINAPI InitGuiCtrlsDLL()
{
// create a new CDynLinkLibrary for this app
new CDynLinkLibrary(GuiCtrlsDLL);
// nothing more to do
}
warning C4273: 'InitGuiCtrlsDLL' : inconsistent dll linkage
I have also export and import definitions, like:
#ifdef _GUICTRLS
#define GUI_CTRLS_EXPORT __declspec(dllexport)
#else
#define GUI_CTRLS_EXPORT __declspec(dllimport)
#endif
Difference between internal and no linkage
Please refer to the following code that is in the same translation unit:
static int global_var; // file scope in C and global namespace scope in C++
// internal linkage
void f(void)
{
static int local_var; // block scope in C and local scope in C++
// no linkage
}
My understanding is this:
My questions:
EDIT
After the answer and comments of James Kanze, I am now able to construct an example that shows the difference between the internal and no linkage attributes:
static int i; // definition
// static storage
// internal linkage
void f(void)
{
extern int i; // declaration
// refers to the static i at file scope
// note that even though the specifier is extern
// its linkage is intern (this is legal in both C/C++)
{
int i; // definition
// automatic storage
// no linkage
}
}
Some articles that do a good job at explaining the concepts involved:
- Scope regions in C and C++
- Storage class specifiers and storage duration
- Linkage in C and C++
How can one register a dependency property whose value is calculated using the value of another dependency property?
Because the .NET property wrappers are bypassed by WPF at run-time, one should not include logic in the getters and setters. The solution to that is typically to use PropertyChangedCallback
s. But those are declared static.
For example, what is the proper way to accomplish this contrived task:
public bool TestBool
{
get { return (bool)GetValue(TestBoolProperty); }
set
{
SetValue(TestBoolProperty, value);
TestDouble = ((value)?(100.0):(200.0)); // HERE IS THE DEPENDENCY
}
}
public static readonly DependencyProperty TestBoolProperty =
DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel));
public double TestDouble
{
get { return ((double)GetValue(TestDoubleProperty)); }
set { SetValue(TestDoubleProperty, value); }
}
public static readonly DependencyProperty TestDoubleProperty =
DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel));
As long as the dependency is not circular, is there a proper means to accomplish this?
Struct vs. Function Definitions in ScopeSo, as far as I know, this is legal in C:
foo.c
struct foo {
int a;
};
bar.c
struct foo {
char a;
};
But the same thing with functions is illegal:
foo.c
int foo() {
return 1;
}
bar.c
int foo() {
return 0;
}
and will result in linking error (multiple definition of function foo
).
Why is that? What's the difference between struct names and function names that makes C unable to handle one but not the other? Also does this behavior extend to C++?
What are ld-linux.so.2 and linux-gate.so.1?When I run ldd program
I get an output of the form
linux-gate.so.1 => (0xb77ae000)
libstdc++.so.6 => /lib/libstdc++.so.6 (0xb76bc000)
libm.so.6 => /lib/libm.so.6 (0xb7691000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7674000)
libc.so.6 => /lib/libc.so.6 (0xb74c2000)
/lib/ld-linux.so.2 (0xb77af000)
Can you explain the output and the reason linux-gate.so.1
and ld-linux.so.2
show differently than other entries? What are their roles?
The following compiles:
static int foo() { return 1; }
int foo();
But, will it always compile? Is the behavior in this case well defined? And what does it means when a non-static prototype follows a static declaration?
Clarification on difference in ODR rules for structs in C and C++I am aware of how ODR, linkage, static
, and extern "C"
work with functions. But I am not sure about visibility of types since they cannot be declared static
and there are no anonymous namespaces in C.
In particular, I would like to know the validity of the following code if compiled as C and C++
// A.{c,cpp}
typedef struct foo_t{
int x;
int y;
} Foo;
static int use_foo()
{
Foo f;
f.x=5;
return f.x;
}
// B.{c,cpp}
typedef struct foo_t{
double x;
} Foo;
static int use_foo()
{
Foo f;
f.x=5.0;
return f.x;// Cast on purpose
}
using the following two commands (I know both compilers autodetect the language based on extensions, hence the different names).
g++ -std=c++17 -pedantic -Wall -Wextra a.cpp b.cpp
gcc -std=c11 -pedantic -Wall -Wextra a.c b.c
Versions 8.3 happily compile both without any errors. Clearly, if both struct symbols have external linkage, there is ODR violation because the definitions are not identical. Yes, compiler is not required to report it, hence my question because neither did.
I do not think so, that is what anonymous namespaces are for.
I am not sure here, I have read that types are considered static
which would make the program valid. Can someone please confirm?
If these definitions were in public header files, perhaps in different C libraries, and a C++ program includes both, each also in a different TU, would that be ODR? How can one prevent this? Does extern "C"
play any role?
Why do we need to use:
extern "C" {
#include <foo.h>
}
Specifically:
When should we use it?
What is happening at the compiler/linker level that requires us to use it?
How in terms of compilation/linking does this solve the problems which require us to use it?
According to C standard:
In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.
In my example we have three separate declarations with each identifier having a different linkage.So why doesn't this work?
static int a; //a_Internal
int main(void) {
int a; //a_Local
{
extern int a; //a_External
}
return 0;
}
Error:
In function 'main': Line 9: error: variable previously declared 'static' redeclared 'extern'
Why does compiler insist that I'm redeclaring instead of trying to access external object in another file?
Valid C++ example for reference:
static void f();
static int i = 0; // #1
void g() {
extern void f(); // internal linkage
int i; // #2 i has no linkage
{
extern void f(); // internal linkage
extern int i; // #3 external linkage
}
}
Both Clang and VC seem to be okay with my C example; only some versions of GCC (not all) produce the aforementioned error.
static keyword in h file and internal linkageYet another static
question.
I have read the following:
And I still fail to understand the following behavior:
I have one h
file:
// StaticTest.h
#include <stdio.h>
static int counter = 0;
struct A {
A () {
counter++;
printf("In A's ctor(%d)\n", counter);
}
~A () {
counter--;
printf("In A's dtor(%d)\n", counter);
}
};
static A a;
And two cpp
files:
// StaticTest1.cpp
#include "StaticTest.h"
int main () {
return 0;
}
And:
// StaticTest2.cpp
#include "StaticTest.h"
The output of the program is:
In A's ctor(1)
In A's ctor(2)
In A's dtor(1)
In A's dtor(0)
Now, A
's constructor is called twice, since the h
file is included twice, and since A
's instance named a
is declared static
, it has internal linkage and the compiler is happy.
Since the counter
is also declared static, it also has internal linkage, and I would expect that it's value will not be shared in the two cpp
files --- but the program output implies the value is shared, since it counts up to 2.
any insights?
EDIT:
Any answers regarding what is considered a "good programming habit" in the context of declaring static variables in h
vs. cpp
files is also welcomed.
I'm trying to develop a dynamic library in C++ to be called by an existing program written in IDL (Interactive Data Language). I know that I need to use extern "C" to disable name mangling so that IDL can call the functions it needs (the rest of the calling mechanism is pretty straightforward).
However, I'm always hesitant to use features of a language that I don't fully understand, so my question is this: What features of C++ do I lose by reverting to C linkage, if any? Namespaces would be an obvious one, I think, but does it completely disable all the other nice features of C++ too? Can I still use the C++ STL, and all the various language features (especially C++11 ones) that I've come to rely on? Or am I stuck essentially coding in C?
Program statically linked to a library but still needs dll to runThere are things that I don't understand when it comes to linking... I'm writing a program using a 3rd party library (the GEOS library). This program has a dependency to geos.lib but still needs geos.dll to run.
I read this question, I think I understand the difference between static and dynamic libraries. What I don't understand is why I still need a dll when I statically link a library.
Determining C executable nameWhen we are compiling a C program the output is stored in a.out. How can we redirect the compiled output to another file?
C++ standard: do namespace-scoped constexpr variables have internal linkage?Imagine we have a header foo.h
containing the following:
#ifndef FOO_H_
#define FOO_H_
namespace foo {
constexpr std::string_view kSomeString = "blah";
}
#endif // FOO_H_
Is foo::kSomeString
guaranteed to have internal linkage in any translation unit that includes foo.h
? Does this vary between C++11 and C++17?
In the draft standard [basic.link]/3 says
A name having namespace scope has internal linkage if it is the name of [...] a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage [...]
But I don't know if constexpr
counts as "const-qualified". Does the standard say so somewhere?
Assuming this is guaranteed to have internal linkage, it seems like there can be no problem with the ODR for this usage, right? (In contrast to what it says in this answer.)
Static functions declared in "C" header filesFor me it's a rule to define and declare static functions inside source files, I mean .c files.
However in very rare situations I saw people declaring it in the header file. Since static functions have internal linkage we need to define it in every file we include the header file where the function is declared. This looks pretty odd and far from what we usually want when declaring something as static.
On the other hand if someone naive tries to use that function without defining it the compiler will complaint. So in some sense is not really unsafe to do this even sounding strange.
My questions are:
This snippet compiles in clang,
namespace A {
void f() {
void g();
g();
}
}
void A::g() { }
but GCC only accepts the code if g
is defined inside the namespace A
as follows:
namespace A {
void f() {
void g();
g();
}
void g() {}
}
But I believe there's nothing in [basic.link]/7 disallowing the first snippet above.
Interface to C++ objects through extern "C" functionsCan an extern "C"
function accept or return C++-specific data types, such as references, pointers-to-members, or non-POD classes (by value)? I cannot find anything in the C++ standard that forbids this. Logically, I would expect the standard to say something about it, as the C ABI is not necessarily suitable for passing such types around.
The reason for me wanting to use C linkage has nothing to do with C compilers. The function is called only from C++ code. I just want to export unmangled function names from my dynamic libraries.
A silly code example:
class Foo {
public:
virtual void doit() = 0;
};
class Bar : public Foo {
public:
void doit() { std::cout << "Bar" << std::endl; }
};
extern "C" Foo& getFoo() { static Bar bar; return bar; }
extern "C" Bar getBar() { return Bar(); }
This compiles with GCC on Linux, and works as expected. Should it, standard-wise?
The question is a follow-up to a discussion in the comments to this question.
Update I have tested this with the Comeau compiler, it didn't complain.
linkage