I have a set of pre defined C source code files that declares defines a lot of static functions - they are just coded up in .c files and not declared in any .h headers file.
Now I am trying to make use of those functions in my C++ application code:
Cmethods.c
static int amethod(int oppcheck)
{
}
A library is created using the C source code files:
$ nm --demangle userlib.a | grep amethod
00000000000001b6 t amethod
CppApp.h
extern "C" { int amethod(int oppcheck); }
CppApp.cpp
#include "CppApp.h"
voit callme()
{
amethod(check);
}
However during compilation ensuring that userlib.a is linked I get below error:
: undefined reference to `amethod'
$ nm --demangle userappcode.a | grep amethod
00000000000001b6 t amethod
U amethod
My further findings is that for functions in C source code files if declared in C header files - the linker error for them never occurs.
Note I cannot touch the C source code files - they are provided by third party community and we cannot break the license.
How can I resolve the issue
I have a set of pre defined C source code files that declares defines a lot of static functions.
Now I am trying to make use of those functions in my C++ application code:
Remove the static from those functions you want to call from some other translation unit.
If you cannot do that, you can't use these functions from outside. And the compiler could even optimize them to the point of removing them from your object file.
(a dirty trick that I do not recommend could be to compile that C code with gcc -Dstatic= to have the preprocessor replace static by nothing)
Note I cannot touch the C source code files.
Then your task is impossible.
You could "augment" the translation units, perhaps by appending to them a public (non static) function calling the static one. For example, you might compile something like
// include the original C code with only `static`
#include "Cmethods.c"
// code a public wrapper calling the static method
extern int public_amethod(int oppcheck);
int public_amethod(int oppcheck) { return amethod(oppcheck); }
Note I cannot touch the C source code files - they are provided by third party community and we cannot break the license -
It looks like you might not be legally allowed to compile that code, or that you cannot distribute its object file. There are no technical tricks to overcome a legal prohibition. If that goes in court, you'll probably lose!
Your issue is not technical, but social and legal. You may need a lawyer. You could also talk with the provider of the original code, and ask him if you are allowed to do what you want.
(without more motivation and context, your question looks weird)
static functions in C and static member functions in C++ are two different things. In C, a static function it is limited to its translation unit and invisible outside, this essential means object file(.o/.obj).
In C++, static can also apply to member functions and data members of classes. A static data member is also called a "class variable", while a non-static data member is an "instance variable".
If you defined amethod with static, then the function will have a internal linkage which means you can't link this function from other source files.
internal linkage.
The name can be referred to from all scopes in the
current translation unit. Any of the following names declared at
namespace scope have internal linkage
variables, functions, or function templates declared static
non-volatile non-inline (sinceC++17) const-qualified variables
(including constexpr) that aren'tdeclared extern and aren't previously
declared to have external linkage.
data members of anonymous unions
you might not touch the C source but a hacky solution is to #include it into a different translation unit with functions that forward the statics. This is not something I would recommend as a general answer but ...
file1.c:
static void function1(int)
{ ...}
file2.c:
#include "file1.c"
void fwd_function1(int x)
{
function1(x);
}
Related
Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
However, reviewing some C++ code tonight, I found this in a class's header file...
public:
UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh??
private:
UInt32 _numberChannels;
So why is there an implementation in a header? Does it have to do with the const keyword? Does that inline a class method? What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
The true purpose of a header file is to share code amongst multiple source files. It is commonly used to separate declarations from implementations for better code management, but that is not a requirement. It is possible to write code that does not rely on header files, and it is possible to write code that is made up of just header files (the STL and Boost libraries are good examples of that). Remember, when the preprocessor encounters an #include statement, it replaces the statement with the contents of the file being referenced, then the compiler only sees the completed pre-processed code.
So, for example, if you have the following files:
Foo.h:
#ifndef FooH
#define FooH
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
#endif
Foo.cpp:
#include "Foo.h"
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
#include "Foo.h"
Foo f;
UInt32 chans = f.GetNumberChannels();
The preprocessor parses Foo.cpp and Bar.cpp separately and produces the following code that the compiler then parses:
Foo.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
Foo f;
UInt32 chans = f.GetNumberChannels();
Bar.cpp compiles into Bar.obj and contains a reference to call into Foo::GetNumberChannels(). Foo.cpp compiles into Foo.obj and contains the actual implementation of Foo::GetNumberChannels(). After compiling, the linker then matches up the .obj files and links them together to produce the final executable.
So why is there an implementation in a header?
By including the method implementation inside the method declaration, it is being implicitly declared as inlined (there is an actual inline keyword that can be explicitly used as well). Indicating that the compiler should inline a function is only a hint which does not guarantee that the function will actually get inlined. But if it does, then wherever the inlined function is called from, the contents of the function are copied directly into the call site, instead of generating a CALL statement to jump into the function and jump back to the caller upon exiting. The compiler can then take the surrounding code into account and optimize the copied code further, if possible.
Does it have to do with the const keyword?
No. The const keyword merely indicates to the compiler that the method will not alter the state of the object it is being called on at runtime.
What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
When used effectively, it allows the compiler to usually produce faster and better optimized machine code.
It is perfectly valid to have an implementation of a function in a header file. The only issue with this is breaking the one-definition-rule. That is, if you include the header from multiple other files, you will get a compiler error.
However, there is one exception. If you declare a function to be inline, it is exempt from the one-definition-rule. This is what is happening here, since member functions defined inside a class definition are implicitly inline.
Inline itself is a hint to the compiler that a function may be a good candidate for inlining. That is, expanding any call to it into the definition of the function, rather than a simple function call. This is an optimization which trades the size of the generated file for faster code. In modern compilers, providing this inlining hint for a function is mostly ignored, except for the effects it has on the one-definition-rule. Also, a compiler is always free to inline any function it sees fit, even if it has not been declared inline (explicitly or implicitly).
In your example, the use of const after the argument list signals that the member function does not modify the object on which it is called. In practice, this means that the object pointed to by this, and by extension all class members, will be considered const. That is, trying to modify them will generate a compile-time error.
It is implicitly declared inline by virtue of being a member function defined within the class declaration. This does not mean the compiler has to inline it, but it means you won't break the one definition rule. It is completely unrelated to const*. It is also unrelated to the length and complexity of the function.
If it were a non-member function, then you would have to explicitly declare it as inline:
inline void foo() { std::cout << "foo!\n"; }
* See here for more on const at the end of a member function.
Even in plain C, it is possible to put code in a header file. If you do it, you usually need to declare it static or else multiple .c files including the same header will cause a "multiply defined function" error.
The preprocessor textually includes an include file, so the code in an include file becomes part of the source file (at least from the compiler's point of view).
The designers of C++ wanted to enable object-oriented programming with good data hiding, so they expected to see lots of getter and setter functions. They didn't want an unreasonable performance penalty. So, they designed C++ so that the getters and setters could not only be declared in the header but actually implemented, so they would inline. That function you showed is a getter, and when that C++ code is compiled, there won't be any function call; code to fetch out that value will just be compiled in place.
It is possible to make a computer language that doesn't have the header file/source file distinction, but just has actual "modules" that the compiler understands. (C++ didn't do that; they just built on top of the successful C model of source files and textually included header files.) If source files are modules, it would be possible for a compiler to pull code out of the module and then inline that code. But the way C++ did it is simpler to implement.
As far as I know, there are two kinds of methods, which can be safely implemented inside the header file.
Inline methods - their implementation is copied to places, where they are used, so there is no problem with double-definition linker errors;
Template methods - they are actually compiled at the moment of template instantiation (eg. when someone inputs a type in place of template), so again there is no possibility of double-definition problem.
I believe, your example fits the first case.
C++ standard quotes
The C++17 N4659 standard draft 10.1.6
"The inline specifier" says that methods are implicitly inline:
4 A function defined within a class definition is an inline function.
and then further down we see that inline methods not only can, but must be defined on all translation units:
6 An inline function or variable shall be defined in every translation unit in which it is odr-used and shall
have exactly the same definition in every case (6.2).
This is also explicitly mentioned in a note at 12.2.1 "Member functions":
1 A member function may be defined (11.4) in its class definition, in which case it is an inline member function (10.1.6) [...]
3 [ Note: There can be at most one definition of a non-inline member function in a program. There may be
more than one inline member function definition in a program. See 6.2 and 10.1.6. — end note ]
GCC 8.3 implementation
main.cpp
struct MyClass {
void myMethod() {}
};
int main() {
MyClass().myMethod();
}
Compile and view symbols:
g++ -c main.cpp
nm -C main.o
output:
U _GLOBAL_OFFSET_TABLE_
0000000000000000 W MyClass::myMethod()
U __stack_chk_fail
0000000000000000 T main
then we see from man nm that the MyClass::myMethod symbol is marked as weak on the ELF object files, which implies that it can appear on multiple object files:
"W"
"w" The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked
and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified.
Keeping the implementation in the class header file works, as I'm sure you know if you compiled your code. The const keyword ensures you don't change any members, it keeps the instance immutable for the duration of the method call.
Could someone tell me what's the purpose of declaring static functions outside classes? What's the difference between this 2? Are there any benefits for using static in this situation?
static void someRandomFunction();
int main()
{
someRandomFunction();
return 0;
}
and
void someRandomFunction();
int main()
{
someRandomFunction();
return 0;
}
At namespace scope, static gives a name internal linkage, meaning that it is only accessible within the translation unit that contains the definition. Without static, it has external linkage, and is accessible in any translation unit.
So you'd use static (or, alternatively, an unnamed namespace) when writing a function that's only intended for use within this unit; the internal linkage means that other units can define different functions with the same name without causing naming conflicts.
Non-static functions (and global names in general) are better declared in a header, to make sure that every translation unit that uses them gets the same declaration.
The static keyword on global functions or variables limits the visibility and linkage scope of the function or variable to the current translation unit.
That means that for a function, it can only be called from the current source file, and not from other source files.
A static function remains visible only in file scope. This is a C feature.
The recommended way to do it in C++ is using an anonymous namespace, as in:
namespace // no name, i.e. anonymous
{
void someRandomFunction();
}
int main()
{
someRandomFunction(); // visible only within this file.
return 0;
}
Note that the function body also has to be declared somewhere within the same file since the linker will not try to find it in other (external) translation units.
So void someRandomFunction(); is really a forward declaration for a function that is defined elsewhere in the same file (i.e. in the same translation unit).
If the function is actually called, you will get a linking error unless the function body is defined in the same file.
(The more pedantic technical term is actually not file but translation-unit since the body might be in an #includeed header do not in the actual file per-se. )
static void someRandomFunction();
This has to be used within same compilation unit (source file) and outside that compilation unit, not available for use.
Whereas, if you have
void someRandomFunction();
with one definition acrosss the program, the function can be used by any compilation unit globally across the program
Static methods and static functions are entirely different things.
Static methods are methods of a class instead of an instance (which you already know, as it seems).
Static functions, on the other hand, are function which are available only in the module they are defined in. They are not exported and cannot be put in a header file and used in another c file. This way you can write different functions sharing the same name, and also the compiler may optimize your code more thoroughly by inlining the function, knowing that no other file is dependant on it.
static tells the compiler not add the function to the symbol table for the object file. This effectively means that the linker is unable to find the function which in turn means you can only use the function directly in the current compilation unit. You can however call static functions from another compilation unit if this is done through a function pointer.
Can anybody explain difference between static function defined within class and static function declared e.g. in file.hpp and defined in file.cpp (I can only use this static function within this file ?
Can anybody explain difference between static function defined within class
That means the function is class-wide, and doesn't need to operate on a particular object. In other words, for that function there is no this.
and static function declared e.g. in file.hpp and defined in file.cpp (I can only use this static function within this file ?
That means that that function does not have external linkage, which means other compilation units (i.e. object files) cannot link to it, because it's not in the symbol table.
Thanks for your reply but could you explain why other compilation units cannot link to it ?
First, some terms. Technically, the compiler is just the part that generates object code from source code. The linker later takes a set of object files and "links" them to make the final program.
To make this work, the compiler generates a "symbol table" and puts it in the object file along with the compiled code. This symbol table lists both the symbols for the global variables and functions in the file, as well as the external symbols that code needs to be linked to in order to work.
The linker's job is to read all the object files and match symbols needed by each object file to symbols provided by other object files. If everything is successful, and there aren't any unresolved needed symbols, the link succeeds and you get your program.
What static on a function or global does is simply tell the compiler to not put that symbol in the object file's symbol table. Nothing else; that symbol is still perfectly usable within that same source file. The linker simply never sees the symbol, and thus cannot link anything to it.
Class members cannot be "disappeared" in this manner, so static has a different meaning in the context of a class. (This recycling of the keyword was probably done to avoid adding another reserved word to the language. BTW, Objective-C solved this same problem in a different manner, using the + and - tokens.)
(And static can have yet another meaning when applied to variables declared inside functions or methods, as Mike points out below. In that case it's basically a global variable, but private to the function.)
Could you also explain why inline functions are implicitly defined as static ?
Since inline functions do not exist as independent pieces of code (they are instead merged "in line" into the calling function), they cannot have symbol table entries (there's nothing to link to).
Please refer to this link
A static variable inside a function keeps its value between invocations.
In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.
There is no difference between a static function defined in the global scope, no matter if it's in a header file or in a source file. Unless the header file isn't included anywhere, when the functions in it is never really defined anywhere.
Then phrase you need to learn when talking about static (non-member) functions is translation unit. A translation unit is a source file and all header files included in that source file, after the preprocessor have processed the file and is the actual input to the compiler. A static function is local to the translation unit, which is why there is no difference if it's defined in the source file or a header file.
You can also use an anonymous namespace to define functions, and they will be local to just the translation unit the anonymous namespace is in.
Also note that functions defined as inline are implicitly defined as static as well.
A static member function is part of the class, and can access static member variables without scope prefix. They do of course have to prefixed with the scope of the class to be called. The difference between a static member function and a non-static member function is that static member functions are not part of any specific instance of the class, and so have no this pointer. If you want to access a specific class instances member variable, you have to pass the instance to the static member function through an argument.
Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
However, reviewing some C++ code tonight, I found this in a class's header file...
public:
UInt32 GetNumberChannels() const { return _numberChannels; } // <-- Huh??
private:
UInt32 _numberChannels;
So why is there an implementation in a header? Does it have to do with the const keyword? Does that inline a class method? What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
Ok, not a C/C++ expert by any means, but I thought the point of a header file was to declare the functions, then the C/CPP file was to define the implementation.
The true purpose of a header file is to share code amongst multiple source files. It is commonly used to separate declarations from implementations for better code management, but that is not a requirement. It is possible to write code that does not rely on header files, and it is possible to write code that is made up of just header files (the STL and Boost libraries are good examples of that). Remember, when the preprocessor encounters an #include statement, it replaces the statement with the contents of the file being referenced, then the compiler only sees the completed pre-processed code.
So, for example, if you have the following files:
Foo.h:
#ifndef FooH
#define FooH
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
#endif
Foo.cpp:
#include "Foo.h"
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
#include "Foo.h"
Foo f;
UInt32 chans = f.GetNumberChannels();
The preprocessor parses Foo.cpp and Bar.cpp separately and produces the following code that the compiler then parses:
Foo.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
UInt32 Foo::GetNumberChannels() const
{
return _numberChannels;
}
Bar.cpp:
class Foo
{
public:
UInt32 GetNumberChannels() const;
private:
UInt32 _numberChannels;
};
Foo f;
UInt32 chans = f.GetNumberChannels();
Bar.cpp compiles into Bar.obj and contains a reference to call into Foo::GetNumberChannels(). Foo.cpp compiles into Foo.obj and contains the actual implementation of Foo::GetNumberChannels(). After compiling, the linker then matches up the .obj files and links them together to produce the final executable.
So why is there an implementation in a header?
By including the method implementation inside the method declaration, it is being implicitly declared as inlined (there is an actual inline keyword that can be explicitly used as well). Indicating that the compiler should inline a function is only a hint which does not guarantee that the function will actually get inlined. But if it does, then wherever the inlined function is called from, the contents of the function are copied directly into the call site, instead of generating a CALL statement to jump into the function and jump back to the caller upon exiting. The compiler can then take the surrounding code into account and optimize the copied code further, if possible.
Does it have to do with the const keyword?
No. The const keyword merely indicates to the compiler that the method will not alter the state of the object it is being called on at runtime.
What exactly is the benefit/point of doing it this way vs. defining the implementation in the CPP file?
When used effectively, it allows the compiler to usually produce faster and better optimized machine code.
It is perfectly valid to have an implementation of a function in a header file. The only issue with this is breaking the one-definition-rule. That is, if you include the header from multiple other files, you will get a compiler error.
However, there is one exception. If you declare a function to be inline, it is exempt from the one-definition-rule. This is what is happening here, since member functions defined inside a class definition are implicitly inline.
Inline itself is a hint to the compiler that a function may be a good candidate for inlining. That is, expanding any call to it into the definition of the function, rather than a simple function call. This is an optimization which trades the size of the generated file for faster code. In modern compilers, providing this inlining hint for a function is mostly ignored, except for the effects it has on the one-definition-rule. Also, a compiler is always free to inline any function it sees fit, even if it has not been declared inline (explicitly or implicitly).
In your example, the use of const after the argument list signals that the member function does not modify the object on which it is called. In practice, this means that the object pointed to by this, and by extension all class members, will be considered const. That is, trying to modify them will generate a compile-time error.
It is implicitly declared inline by virtue of being a member function defined within the class declaration. This does not mean the compiler has to inline it, but it means you won't break the one definition rule. It is completely unrelated to const*. It is also unrelated to the length and complexity of the function.
If it were a non-member function, then you would have to explicitly declare it as inline:
inline void foo() { std::cout << "foo!\n"; }
* See here for more on const at the end of a member function.
Even in plain C, it is possible to put code in a header file. If you do it, you usually need to declare it static or else multiple .c files including the same header will cause a "multiply defined function" error.
The preprocessor textually includes an include file, so the code in an include file becomes part of the source file (at least from the compiler's point of view).
The designers of C++ wanted to enable object-oriented programming with good data hiding, so they expected to see lots of getter and setter functions. They didn't want an unreasonable performance penalty. So, they designed C++ so that the getters and setters could not only be declared in the header but actually implemented, so they would inline. That function you showed is a getter, and when that C++ code is compiled, there won't be any function call; code to fetch out that value will just be compiled in place.
It is possible to make a computer language that doesn't have the header file/source file distinction, but just has actual "modules" that the compiler understands. (C++ didn't do that; they just built on top of the successful C model of source files and textually included header files.) If source files are modules, it would be possible for a compiler to pull code out of the module and then inline that code. But the way C++ did it is simpler to implement.
As far as I know, there are two kinds of methods, which can be safely implemented inside the header file.
Inline methods - their implementation is copied to places, where they are used, so there is no problem with double-definition linker errors;
Template methods - they are actually compiled at the moment of template instantiation (eg. when someone inputs a type in place of template), so again there is no possibility of double-definition problem.
I believe, your example fits the first case.
C++ standard quotes
The C++17 N4659 standard draft 10.1.6
"The inline specifier" says that methods are implicitly inline:
4 A function defined within a class definition is an inline function.
and then further down we see that inline methods not only can, but must be defined on all translation units:
6 An inline function or variable shall be defined in every translation unit in which it is odr-used and shall
have exactly the same definition in every case (6.2).
This is also explicitly mentioned in a note at 12.2.1 "Member functions":
1 A member function may be defined (11.4) in its class definition, in which case it is an inline member function (10.1.6) [...]
3 [ Note: There can be at most one definition of a non-inline member function in a program. There may be
more than one inline member function definition in a program. See 6.2 and 10.1.6. — end note ]
GCC 8.3 implementation
main.cpp
struct MyClass {
void myMethod() {}
};
int main() {
MyClass().myMethod();
}
Compile and view symbols:
g++ -c main.cpp
nm -C main.o
output:
U _GLOBAL_OFFSET_TABLE_
0000000000000000 W MyClass::myMethod()
U __stack_chk_fail
0000000000000000 T main
then we see from man nm that the MyClass::myMethod symbol is marked as weak on the ELF object files, which implies that it can appear on multiple object files:
"W"
"w" The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked
and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified.
Keeping the implementation in the class header file works, as I'm sure you know if you compiled your code. The const keyword ensures you don't change any members, it keeps the instance immutable for the duration of the method call.
Consider:
namespace JohnsLib {
static bool foobar();
bool bar();
}
What implications does static have here?
It changes the linkage from "external" to "static", making it invisible to the linker, and unusable from other compilation units. (Well, if other compilation units also include the header, they get their own separate copy)
static at namespace scope means that it is local to a translation unit (i.e. source file). If you define the function in the header file and include this header into multiple C++ files, you won't get redefinition errors because all the functions will be unique(more correctly, the functions will have internal linkage). The same effect can be achieved by means of anonymous namespaces, for example
namespace JohnsLib
{
namespace
{
bool foobar() {definition here, won't cause redefinition errors}
}
bool bar();
}
The result of static keyword in namespace scope (global or user defined namespace) is that such define object will not have external linkage; that is, it will not be available from other translation units and cannot be used as a (non-type one i.e. reference or pointer) template parameter.
In the C++ programming Language Bjarne states In C and C++ programs,
the keyword static is (confusingly) used to mean "use internal
linkage". Don't use static except inside functions and classes.
In Sutter/Alexandrescu C++ Coding Standards Item 61 is "Don't define entities with linkage in a header file."