I have just started learning C++. Can some explain the difference between the following C++ function prototypes?
void f(int n);
extern void f(int n);
static void f(int n);
The void and extern void versions are the same. They indicate that the function has external linkage (i.e. the definition of the function may be expected to come from some other C or C++ file). Static indicates that the function has internal linkage, and will exist only in the current C++ file.
You almost never see these specifiers applied to functions because 99.9% of the time you want the default extern behavior.
You may see the static or extern storage specifiers on global variables though, which is often done to reduce name conflicts with other files in the same project. This is a holdover from C; if you're using C++ this kind of thing should be done with an anonymous namespace instead of static.
This is more of a C-language question than a C++ one, but:
void f(int n);
Declares a function f that takes a single integer parameter.
extern void f(int n);
Declares a function f that takes a single integer parameter but exists in some other file. The compiler will trust that you have implemented the function somewhere. If the linker cannot find it, you will get a linker error.
static void f(int n);
Declares a function f that takes a single integer parameter. The static keyword makes this interesting. If this is in a .cpp file, the function will only be visible to that file. If it is in a .h file, every .cpp file that includes that header will create its own copy of that function that is only accessible to that implementation file.
The first two are the same thing. The third one gives f internal linkage, meaning that a different source file may use the name f to be something different.
The use of static as in that third example should not be used. Instead use an anonymous namespace:
namespace { // anonymous
void f(int n);
}
Both answers so far have deprecated the use of static functions. Why? What makes
namespace {
void f(int n);
}
superior to
static void f(int n);
? It's not simpler, it's not easier to understand...
Anonymous namespace is a more universal and cleaner solution, you can have functions, variables, classes in it. And static is way too overloaded, in some contexts meaning internal linkage, in others static lifetime.
There is one disadvantage of anonymous namespace though. Because of external linkage, the exported section of your object/library files will swell with all those long <unique namespace name>::<function> names which wouldn't be there is they were static.
Related
I have a DLL in pure C code. I would like to find a way to remove the library name prefix from the functions, classes, and structs; EX:
// lib.h
void foobar();
// lib.hpp
namespace foo {
bar();
}
I would like to avoid simply writing a wrapper for every function, since I'd have to write it for every time I want to add a function. Is there a better / more efficient way of writing this?
I started writing the wrapper idea, but there's a lot of functions to write this for. Void pointers worked a little better, but still had the same issue.
Unless you are worried about name conflicts between existing C++ function names and the C library, how about just using extern "C" (in your C++ code) and call it (from your C or C++ code). For example:
extern "C" void f(int); // apply to a single function
extern "C" { // or apply to a block of functions
int g(double);
double h(void);
};
void code(int i, double d)
{
f(i);
int ii = g(d);
double dd = h();
// ...
}
When code is enclosed within an extern “C” block, the C++ compiler ensures that the function names are un-mangled – that the compiler emits a binary file with their names unchanged, as a C compiler would do.
This approach is commonly used to accommodate inter language linkage between C++ and C.
from this Reference
more from cppprefference.com
You could try this:
// lib.hpp
namespace foo {
constexpr auto bar = foobar;
}
This should create a function pointer, and because it is constexpr, it should get resolved at compile time, so no performance hit. Also, constexpr is implicitly inline, so that (or static) can be omitted from this definition.
There are two implications of using the inline keyword(§ 7.1.3/4):
It hints the compiler that substitution of function body at the point of call is preferable over the usual function call mechanism.
Even if the inline substitution is omitted, the other rules(especially w.r.t One Definition Rule) for inline are followed.
Usually any mainstream compiler will substitute function body at the point of call if needed, so marking function inline merely for #1 is not really needed.
Further w.r.t #2, As I understand when you declare a function as static inline function,
The static keyword on the function forces the inline function to have an internal linkage(inline functions have external linkage) Each instance of such a function is treated as a separate function(address of each function is different) and each instance of these functions have their own copies of static local variables & string literals(an inline function has only one copy of these)
Thus such a function acts like any other static function and the keyword inline has no importance anymore, it becomes redundant.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
So, Is using static and inline together on a function practically useless?
Your analysis is correct, but doesn't necessarily imply uselessness. Even if most compilers do automatically inline functions (reason #1), it's best to declare inline just to describe intent.
Disregarding interaction with inline, static functions should be used sparingly. The static modifier at namespace scope was formerly deprecated in favor of unnamed namespaces (C++03 §D.2). For some obscure reason that I can't recall it was removed from deprecation in C++11 but you should seldom need it.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
There's no notion of preference. static implies that different functions with the same signature may exist in different .cpp files (translation units). inline without static means that it's OK for different translation units to define the same function with identical definitions.
What is preferred is to use an unnamed namespace instead of static:
namespace {
inline void better(); // give the function a unique name
}
static inline void worse(); // kludge the linker to allowing duplicates
Static and inline are orthogonal (independent). Static means the function should not be visible outside of the translation unit, inline is a hint to the compiler the programmer would like to have this function inlined. Those two are not related.
Using static inline makes sense when the inlined function is not used outside of the translation unit. By using it you can prevent a situation of accidental violation of ODR rule by naming another inlined function in another tranlation unit with the same name.
Example:
source1.cpp:
inline int Foo()
{
return 1;
}
int Bar1()
{
return Foo();
}
source2.cpp:
inline int Foo()
{
return 2;
}
int Bar2()
{
return Foo();
}
Without using static on Foo (or without using an anonymous namespace, which is preferred way by most C++ programmers), this example violates ODR and the results are undefined. You can test with Visual Studio the result of Bar1/Bar2 will depend on compiler settings - in Debug configuration both Bar1 and Bar2 will return the same value (inlining not used, one implementation selected randomly by the linker), in Release configuration each of them will return the intended value.
I may not be completely right about this, but as far as I know declaring a function static inline is the only way to make (or allow) the compiler to generate a machine code where the function really is not defined in the compiled code at all, and all you have is a direct substitution of the function call into a sequence of instructions, like it were just a regular procedure body, with no trace in the machine code of a procedure call relative to that function definition from the source code.
That is, only with static inline you can really substitute the use of a macro, inline by itself is not enough.
A simple Google search for "static inline" will show you compiler documentation pages that talk about it. I guess this should be enough to answer your question, and say, "no, it is not practically useless". Here is one example of a site discussing the use of inline, and specifically of static inline http://www.greenend.org.uk/rjk/tech/inline.html
If you talk about free functions (namespace scope), then your assumption is correct. static inline functions indeed don't have much value. So static inline is simply a static function, which automatically satisfies ODR and inline is redundant for ODR purpose.
However when we talk about member methods (class scope), the static inline function does have the value.
Once you declare a class method as inline, it's full body has to be visible to all translation units which includes that class.
Remember that static keyword has a different meaning when it comes for a class.
Edit: As you may know that static function inside a class doesn't have internal linkage, in other words a class cannot have different copies of its static method depending on the translation (.cpp) units.
But a free static function at namespace/global scope does have different copies per every translation unit.
e.g.
// file.h
static void foo () {}
struct A {
static void foo () {}
};
// file1.cpp
#include"file.h"
void x1 ()
{
foo(); // different function exclusive to file1.cpp
A::foo(); // same function
}
// file2.cpp
#include"file.h"
void x2 ()
{
foo(); // different function exclusive to file2.cpp
A::foo(); // same function
}
I just read a man page for gcc and it specifically states the use of static inline with a compiler flag. In the case of the flag, it inlines the function and if it is also static and is inlined in every instance that it is called, then it gets rid of the function definition which will never be used in the created object file, thereby reducing the size of the generated code by that little bit.
I am working on a project in C::B and need to use global instances of classes, across the multiple project files. (I'm new to usage of header files and global classes)
I have declared, defined, initialized classes and functions thus:
//in complex.h
class Julia
{
public:
double R;
double I;
void algorithm();
};
Julia J;
//in complex.cpp
#include "complex.h"
void Julia::algorithm()
{
//fn body here
}
//in main.cpp
#include"complex.h"
int main()
{
//calls initialize() and display()
}
void initialize()
{
//...some code(irrelevant)
cin>>J.R>>J.I;
}
void display()
{
J.algorithm();
//some more (irrelevant) code
}
On building and running the code, I get the error- "first defined here" and the Build log shows :
obj\Debug\complex.o:complex.cpp:(.bss+0x3bf0): multiple definition of `J'
obj\Debug\main.o:C:/Users/ShA/Documents/etf_build/main.cpp:20: first defined here
[This is for my 12th grade school project, and I don't think I would be allowed to use singletons (restrictions), even though they seem to be suitable. ]
Can somebody point out the possible errors in the code and how to find a solution to the errors I'm getting?
The declaration
Julia J;
in your header is a definition of J, and via inclusion of the header you have this definition in two translation units: the main.cpp translation unit and the complex.cpp translation unit.
The linker doesn't know that they're (were intended to be) the same definition.
As the linker sees it, it's two separate and conflicting definitions of the same thing.
A purely technical solution is to make J a singleton, and a simple way to do to that is via a static variable in a function, which is called a “Meyers' singleton”:
inline
auto J()
-> Julia&
{
static Julia the_object;
return the_object;
}
The technical solution above is ungood because the singleton, like the direct global variable, introduces complex arbitrary lines of communication, e.g. as via your init function.
There is an even more ungood possible technical solution of declaring the variable as extern in the header, and defining it in the corresponding implementation file. That's extra ungood because in the more general case it runs the risk of using the variable uninitialized. That's called the “static initialization order fiasco”, and is discussed in the C++ FAQ.
Instead of these technical workarounds you should change the design and let main create the Julia instance.
It can be passed down to invoked functions.
If you find that it's passed to a number of functions, in particular as a first argument, then maybe these functions should be member functions of the Julia class, or maybe you should then introduce a new class for this.
in complex.h
Julia J;
This is your error. Any source file that #includes complex.h has its own version of J. This violates the one definition rule.
If the only place you are using the global variable J is in your int main, there is no reason to make that variable global. Make J a local variable inside your main function. Declaring a global variable that is used in only one place is just wrong.
On the other hand, if you are using that variable in multiple files, what you are doing is also wrong. In this case, your complex.h header file should qualify your variable J with the extern keyword. Now you can reference that global in multiple places (but beware the static initialization fiasco). You can reference that variable in multiple places. You need to define that variable in exactly one place.
Place a static Julia& GetInstance() function inside your class Julia declaration (in the header file).
Place an instance of the Julia (Julia J) inside the source file. Then inside the GetInstance() implementation (also in the source file), return J.
Complex.h
class Julia
{
public:
double R;
double I;
void algorithm();
static Julia& getInstance();
};
Complex.c
#include "complex.h"
Julia J;
void Julia::algorithm()
{
//fn body here
}
Julia& Julia::getInstance() { return J; }
I'm a C++ noob. I have a foo.cpp file which defines a function,
void sort() {
// details of sort algorithm
}
I have not defined this in the corresponding header file, but I get no compilation error. I noticed this is taken as a static method. Is that the case? What exactly have I done here?
EDIT:
I've noticed that inside this method I can't use this, (ex: this->bar), hence my assumption that this is a static function. This actually happened when I wanted a 'private' method, but forgot to declare it in the header file. Is there an actual use of such a function?
It is not invisible outside of that compilation unit, it is not bound to a single compilation unit, it is just a definition that needs a declaration in order to be called. Like any other definition.
wtf.cpp:
#include <iostream>
void f(){ std::cout<< "f();"; }
omg.cpp:
void f(); // I can declare wherever I use it.
int main(){ f(); }
$ g++ wtf.cpp omg.cpp && ./a.out
Output: f();
No, it is not taken as a static function. It is just not visible to the other transllation unnits, and so you cannot use it.
The difference in regard to a static method is, that the linker sees the function. So if you define a function with the same name in another translation unit, you will probably either get a linker error (best case) or the wrong method called at times.
PS: I talk about a functions rather than methods here, because in C++ a method typically is part of a class, and you cannot define a method for a class if that method isn't declared in that class' declaration.
the function is like the others said available in that translation unit.
But you can still access it from anywhere as it will just have external linkage. so just do this:
void foo()
{
extern void sort();
sort();
}
Nothing happens. The function will be there and essentially available, but without a prototype/forward declaration other translation units/parts of the code won't know it's actually there (and based on optimization level it might be excluded from the resulting executable code).
You've created a function that is only visible to that compilation unit (and others that include the source itself).
You've just have defined a free function .
You can use in your implementation file given that the declaration is above the calls (the parser "reads" the source file from top to bottom) :
void fun(){
mysort(); // Compile Error
void mysort(){}
void anotherFun(){
mysort(); // Works here
}
To get rid of this boundary effect, you can add a prototype of the function at the beginning of the file. I often use this "free function" for small conversion macros.
Example :
char* BigEndianToLitteEndian( char word[], int size); // prototype
void routine()
{
....
le = BigEndianToLittleEndian( be, SIZE );
....
}
char* BigEndianToLitteEndian( char word[], int size){ // implementation
....
}
Even though it's only in the implementation file, it's not static unless you specify static.
Static functions, in addition to restricting access, may also allow for compiler optimizations for better performance.
See static function in C, notably #Stephen_Canon's answer.
And also it might be very bad if the same function defined inside some other cpp file with the same signature.
Given the following header file, if 'a' is defined inside the main body, I get a warning "unused variable 'a'" and linker error "undefined reference to 'a'.
header.h:
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
extern int* a;
void f()
{
std::cout<<*a <<std::endl;
return;
}
#endif
main.cpp:
#include "header.h"
int main()
{
int* a = new int(10);
f();
}
However, if 'a' is defined outside of main(), the program links with no errors and f() works as expected (prints 10). Why is this?
Example:
int* a = new int(10);
int main()
{
f();
}
int* a = new int(10);
for this line, if in the main function, you are defining a local variable.
so the extern int* a; only declare a variable, but not define it. then get a linkage error on that symbol
You need to learn about name binding, which determines how two
declarations of the same name are related. When you define a variable
within a function, its name has no linkage; i.e. the entity it refers to
is distinct from any other entity in the program.
More generally: a declaration (and in this sense, a definition is also a
declaration) associates a symbol with an entity—an object (in
which case, the declaration declares a variable), a function, a
reference, a type or anything else you can declare in C++. Whether
different declarations of the same name associate with the same entity
or not is defined by their linkage. C++ recognizes three
different types of linkage:
external linkage, in which the entity can be referred to by declarations in other transation units,
internal linkage, in which the entity can be referred to by other declarations in the same translation unit,
and no linkage, in which the entity cannot be referred to by any other declaration.
Variables declared at block scope (i.e. local variables) have no
linkage, unless they are explicitly declared extern (and a local
variable declared extern cannot be a definition). So the int a in
main declares (and defines) an entity which is independent of any
other a in the program. Variables declared in namespace scope have
external linkage, unless they are declared static, in which case they
have internal linkage; when you define int a at namespace scope, it
has external linkage, and so refers to the same entity you declared with
extern int a in the header.
When you define the variables inside main, it only has scope inside the main function.
The global extern cannot resolve to that. In other words the linker cannot match the extern declared globally to the variable definition inside the main function.
If you define a inside of main, then its scope (visibility) is restricted to main -- an extern declaration will not make it visible anywhere else.
You have to define it at namespace scope (i.e., outside any function) for it to be visible in other translation units.
It's rather annoying to read 4 answers explaining what's wrong, but none explaining how the correct way to fix it. It's probably a safe guess that if the OP doesn't know about scoping he probably also doesn't know about passing variables to a function.
The Problem
You're trying to get at the value of a variable, but the variable is in another function. How can I get at it? Well, the simple answer is, you don't WANT to get at it. You heard me right. The entire reason to use a function is reusability, if you tie your newly created function to another function then you can't use it everywhere. Remember, functions help you be lazy. And a good programmer is a lazy programmer. If you can write a function once and use it in a million places, you're doing it right. ;)
But I still really want to get at the value of that variable
Then you want to use a function parameter to pass the variable to the function.
Functions are named because you can think of them in terms of math. Put variables in, get out useful data after the function has run and done interesting things with those variables. So let's say you have a math function y = f(x), the equivalent of this would be int f(int x) { /*stuff here*/ } then you call it in your main function using int y = f(a) where a is some variable or number.
You want to avoid global variables because they don't always do what you expect (especially if you have a lot of code, it's very easy to accidentally use the same name.)
In your case you want the function to print out the contents of a specific variable, so I think perhaps you're seeking a way use that function with any specific variable. So here's how you do that.
void f(); //hi, I'm a function prototype
void f(int a); //hi, I'm a function prototype that takes a parameter
void f(int a, int b); //hi, I'm a function prototype that takes two parameters (both ints)
void f(int a, ...); //hi, I'm a function prototype that takes an int then any number of extra parameters (this is how printf works.)
So what you really want to do is change your code to something like:
header.h:
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
// extern int* a; // We don't need this
void f(int* a)
{
if (a != NULL) //always, always check to make sure a pointer isn't null (segfaults aren't fun)
std::cout<<*a <<std::endl;
//return; //Don't really need this for a function declared void.
}
#endif
main.cpp:
#include "header.h"
int main()
{
int* a = new int(10);
f(a);
return 0; //main is declared as returning an int, so you should.
}
Functions by value, pointer and reference
So, in your examples I gave I used int rather than int* in your example. The difference between the two is the first one passes the parameter by value. The other by pointer. When you pass a variable to a function a copy of it is ALWAYS made. If you pass it a int, it makes a copy of the int, if you pass it a 4 MB structure it will make a copy of the 4MB structure, if you pass it a pointer to a 4MB structure is will make a copy of the pointer (not the entire structure.) This is important for two reasons:
Performance: Making a copy of a 4MB structure takes some time.
Ability to change contents: If you make a copy of the pointer, the original data is still in the same place and still accessible through the pointer.
What if you want 1 and not 2? Well then you can declare the pointer const. The prototype looks like this: int f(int const* a);
What if you want 2 and not 1? Tough cookies (there no good reason anyway.)
Finally, you can also declare a function to take a reference and not a pointer, the big difference between a reference and a pointer is a reference will not be NULL (and you can't use pointer arithmetic on a reference.) You will want to use either pass by reference or pass by value normally. Needing to pass by pointer is something that I almost never need to do, in my experience it's more of a special case sort of thing.
Pass by reference: int f(int& a);
Pass by const reference: int f(int const& a);
So to sum up:
if you have function that needs parameters:
then:
if you do not need to modify the contents:
then:
if the size of the variable is small:
pass by value: int f(int a);
else if the size of the variable is large:
then:
if the value of the address can be NULL:
pass by const pointer: int f(int const* a);
else:
pass by const reference: int f(int const& a);
else if you do need to modify the contents:
then:
if the value of the address can be NULL:
pass by pointer: int f(int* a);
else:
pass by reference: int f(int& a);
There's some more cases, but these are the main ones, see this website for more details.
When you define the variable in the function main it is valid only in the scope of main. You can define in all function a variable with the name a. But these would be different variables, because each has it's owen scope.
Technically the variable is allocated on the stack while the function is called, therefore each instance has its own storage.