Linkage between files - how exactly does it work? - c++

So I've been reading about this but couldn't find anything that'd explain the behavior of this code below to me:
header.hpp:
class TESTING{
private:
int num;
public:
TESTING(int);
};
void testing(int, int);
def.cpp:
#include "header.hpp"
#include <iostream>
using namespace std;
TESTING::TESTING(int num = 100){
this->num = num;
cout << "init with: " << this->num << endl;
}
void testing(int a = 500, int b = 200){
cout << "a: " << a << ", b: " << b << endl;
}
int main(){
TESTING test1;
TESTING test2(5);
testing();
testing(1);
testing(1, 2);
}
So far so good and working as intended, the output then is:
init with: 100
init with: 5
a: 500, b: 200
a: 1, b: 200
a: 1, b: 2
But then when I cut the "int main" function and paste it into the following Main.cpp below
Main.cpp:
#include "header.hpp"
int main(){
//TESTING test1;//error: assumed to be default constructor
TESTING test2(5);
//testing();//error: too few arguments
//testing(1);//error: too few arguments
testing(1, 2);
}
I'd get the errors mentioned in the comments above but still the output:
init with: 5
a: 1, b: 2
Which then means that it does link itself to def.cpp but with some sort of minimum visibility(?).
Why's this happening?
The purpose of this Main.cpp file is to have the main function that'll run all the other c++ files in that project, is there a general better way to achieve that than the way I tried? If so, does that way apply to the code mentioned here? Or is my code just written badly?
P.S: I'm new to c++, please be gentle :d

Default arguments don't magically transfer across source files. Think about it - how is the compiler processing main.cpp supposed to know that, in a different source file, you gave default arguments to some parameters?
Formally, default arguments are specific to any given scope:
8.3.6/4 For non-template functions, default arguments can be added in later declarations of a function in the same scope. Declarations in
different scopes have completely distinct sets of default arguments...
Even in the same source file, you can declare the same function to have different default arguments in different scopes. The compiler would happily substitute whatever default arguments, if any, are specified by the declaration visible in the current scope.
On an unrelated note, the word "linkage" is a term of art - it has a very specific meaning in C++. This notion of linkage is largely irrelevant to your question, at least insofar as it relates to default arguments (I just point it out for the benefit of readers who might be confused by the question's title). The set of default arguments is not part of the function name or signature, and doesn't affect its linkage, its ability to be used across scopes and translation units.

Related

Does int main() need a declaration on C++?

I was taught that functions need declarations to be called. To illustrate, the following example would give me an error as there is no declaration for the function sum:
#include <iostream>
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
// main.cpp:4:36: error: use of undeclared identifier 'sum'
// std::cout << "The result is " << sum(1, 2);
// ^
// 1 error generated.
To fix this, I'd add the declaration:
#include <iostream>
int sum(int x, int y); // declaration
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
int sum(int x, int y) {
return x + y;
}
Why the main function doesn't need the declaration, as other functions like sum need?
A definition of a function is also a declaration of a function.
The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:
If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as B.h).
If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.
In C++, a user program never calls main, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main in this regard.) In C, a program can call main. In that case, it does require that a declaration be visible before the call.
Note that main does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main it needs in order to call it properly.
I was taught that functions need declarations to be called.
Indeed. A function must be declared before it can be called.
why we don't add a declaration for the main function?
Well, you didn't call main function. In fact, you must not call main at all1, so there is never a need to declare main before anything.
Technically though, all definitions are also declarations, so your definition of main also declares main.
Footnote 1: The C++ standard says it's undefined behaviour to call main from within the program.
This allows C++ implementations to put special run-once startup code at the top of main, if they aren't able to have it run earlier from hooks in the startup code that normally calls main. Some real implementations do in fact do this, e.g. calling a fast-math function that sets some FPU flags like denormals-are-zero.
On a hypothetical implementation, calling main could result in fun things like re-running constructors for all static variables, re-initializing the data structures used by new/delete to keep track of allocations, or other total breakage of your program. Or it might not cause any problem at all. Undefined behaviour doesn't mean it has to fail on every implementation.
The prototype is required if you want to call the function, but it's not yet available, like sum in your case.
You must not call main yourself, so there is no need to have a prototype. It's even a bad a idea to write a prototype.
No, the compiler does not need a forward declaration for main().
main() is a special function in C++.
Some important things to remember about main() are:
The linker requires that one and only one main() function exist when creating an executable program.
The compiler expects a main() function in one of the following two forms:
int main () { /* body */ }
int main (int argc, char *argv[]) { /* body */ }
where body is zero or more statements
An additional acceptable form is implementation specific and provides a list of the environment variables at the time the function is called:
int main (int argc, char* argv[], char *envp[]) { /* body */ }
The coder must provide the 'definition' of main using one of these acceptable forms, but the coder does not need to provide a declaration. The coded definiton is accepted by the compiler as the declaration of main().
If no return statement is provided, the compiler will provide a return 0; as the last statement in the function body.
As an aside, there is sometimes confusion about whether a C++ program can make a call to main(). This is not recommended. The C++17 draft states that main() "shall not be used within a program." In other words, cannot be called from within a program. See e.g. Working Draft Standard for C++ Programming Language, dated "2017-03-21", Paragraph 6.6.1.3, page 66. I realize that some compilers support this (including mine), but the next version of the compiler could modify or remove that behavior as the standard uses the term "shall not".
It is illegal to call main from inside your program. That means the only thing that is going to call it is the runtime and the compiler/linker can handle setting that up.This means you do not need a prototype for main.
A definition of a function also implicitly declares it. If you need to reference a function before it is defined you need to declare it before you use it.
So writing the following is also valid:
int sum(int x, int y) {
return x + y;
}
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
If you use a declaration in one file to make a function known to the compiler before it is defined, then its definition has to be known at linking time:
main.cpp
int sum(int x, int y);
int main() {
std::cout << "The result is " << sum(1, 2);
return 0;
}
sum.cpp
int sum(int x, int y) {
return x + y;
}
Or sum could have its origin in a library, so you do not even compile it yourself.
The main function is not used/referenced in your code anywhere, so there is no need to add the declaration of main anywhere.
Before and after your main function the c++ library might execute some init and cleanup steps, and will call your main function. If that part of the library would be represented as c++ code then it would contain a declaration of int main() so that that it could be compiled. That code could look like this:
int main();
int __main() {
__startup_runtime();
main();
__cleanup_runtime();
}
But then you again have the same problem with __main so at some point there is no c++ anymore and a certain function (main) just represents the entry point of your code.
Nope. You can't call it anyway.
You only need forward declarations for functions called before they are defined. You need external declarations (which look exactly like forward declarations on purpose) for functions defined in other files.
But you can't call main in C++ so you don't need one. This is because the C++ compiler is allowed to modify main to do global initialization.
[I looked at crt0.c and it does have a declaration for main but that's neither here nor there].

error: statement cannot resolve address of overloaded function C++

I am studying C++ by book and was trying to test simple coding for a looped game combat. A switch inside a while loop.
damage = greatsword[0] + player[1] - enemy[2]; endl;
error: statement cannot resolve address of overloaded function|
I have this error in 4 different code lines and in each one it has 'damage' so I assume its some problem with that. I have damage declared as an int and set to 0 before trying to change it to the attack value. I can provide more of the code if needed. I also tried changing the name from x to dmg to see if that was the problem
You have a trailing endl; which you probably did not mean to include. std::endl is a function which is used when printing to an output stream; usually you'll see cout << ... << endl;, but otherwise it should not be used.
std::endl, as used as a stream manipulator, is actually a function.
You probably achieve a similar or related error message by doing this
void f(); // don't need to define f()
int main()
{
f; // should be f() to call the function
}
So remove the statement endl;

A couple of basic questions regarding "Hello World"

So I just started teaching myself C++ and I have two newbie questions regarding the Hello World exercise.
#include <iostream>
using namespace std; [1]
int main()
{
cout << "Hello, World" << endl; [2]
return 0;
}
[1] Is this line of code necessary? If not, why? It worked without it but I found a source that used it and was wondering why was this used.
[2] On my first try I forgot to add endl and the code worked. When I went to check I realised this was missing so why did it still work anyway?
Really basic questions but I want to understand the basics well.
Many thanks in advance.
Is this line of code necessary? If not, why? It worked without it but I found a source that used it and was wondering why was this used.
Namespace
First of all you should have to understand what a namespace is.
That's an argument reference:
Namespace.
Pratically a namespace is like a container. You can keep different
symbol's names. In that way, in very large project, it is possible define two different symbols (e.g two functions) with the same name.
I try to give you a little example:
I can define two different functions foo with the same name. It possibile because I put them inside two different namespaces.
namespace my_ns1 {
void foo(int a) {
return a;
}
}
namespace my_ns2 {
void foo(int a) {
return a + 2;
}
}
When I want to call the first foo function the proper invokation
will be:
my_ns1::foo(10); // return 10
If i want to call the second foo function, then:
my_ns2::foo(10); // return 12
In a specific block I can specify the intent to use always a namespace
with the code:
using namespace my_ns1;
In that way there is no more need to specify the "full name" of the function.
The standard library keeps all its function in a proper namespace: std.
So when you want to use a function in the standard library you have to invoke it with something like:
std::function(...)
If you use the code
using namespace std;
At the begin of your file, you're just saying to "open" that namespace
and you can call all function without std::
The namespace is usefull in order to prevent name conflict.
[2] On my first try I forgot to add endl and the code worked. When I went to check I realised this was missing so why did it still work anyway?
Simply
std::endl
is a proper way to insert the '\n' character which means "an end of line".

How to keep track of call statistics? C++

I'm working on a project that delivers statistics to the user. I created a class called Dog,
And it has several functions. Speak, woof, run, fetch, etc.
I want to have a function that spits out how many times each function has been called. I'm also interested in the constructor calls and destructor calls as well.
I have a header file which defines all the functions, then a separate .cc file that implements them. My question is, is there a way to keep track of how many times each function is called?
I have a function called print that will fetch the "statistics" and then output them to standard output. I was considering using static integers as part of the class itself, declaring several integers to keep track of those things. I know the compiler will create a copy of the integer and initialize it to a minimum value, and then I'll increment the integers in the .cc functions.
I also thought about having static integers as a global variable in the .cc. Which way is easier? Or is there a better way to do this?
Any help is greatly appreciated!
Using static member variables is the way to go. However, the compiler will not "create a copy of the integer and initialize it to a minimum value"; you'll have to provide a definition for each one in the .cc file and initialize it to 0 there. (Things are a bit different if you're using C++11, but the basic idea is the same.)
There's no reason to use static global variables instead of static members.
foo.h:
class Foo {
static int countCtor_;
static int countDtor_;
static int countprint_:
Foo();
~Foo();
static void print();
};
foo.cc:
#include <iostream>
#include "foo.h"
int Foo::countCtor_ = 0;
int Foo::countDtor_ = 0;
int Foo::countprint_ = 0;
Foo::Foo() {
++countCtor_;
// Something here
}
Foo::~Foo() {
++countDtor_;
// Something here
}
void Foo::print() {
++countprint_;
std::cout << "Ctor: " << countCtor_ << "\n"
<< "Dtor: " << countDtor_ << "\n"
<< "print: " << countprint_ << "\n";
}
But if you've got a lot of functions, the repetition involved is a bit annoying—it's very easy to accidentally do ++countBar_ when you meant ++countBaz_ (especially if you copy and paste the boilerplate), so you may want something a bit fancier, such as a static map and a macro that increments counts[__FUNC__], so you can just use the exact same line in each function. Like this:
foo.h:
#include <map>
class Foo {
static std::map<const char*, int> counts_;
Foo();
~Foo();
void print();
};
foo.cc:
#include <iostream>
#include "foo.h"
std::map<const char *, int> Foo::counts_;
#define INC_COUNT_() do { ++counts_[__FUNC__]; } while (0)
Foo::Foo() {
INC_COUNT_();
// Something here
}
Foo::~Foo() {
INC_COUNT_();
// Something here
}
void Foo::print() {
INC_COUNT_();
for (std::map<const char *, int>::const_iterator it = counts_.begin();
it != counts_.end(); ++it) {
std::cout << it->first << ": " << it->second << "\n";
}
}
In the example code above, __FUNC__ is a placeholder. Unfortunately, there is no standard-compliant value you can use in its place. Most compilers have some subset of __func__, __FUNC__, __FUNCTION__, __FUNCSIG__, and __PRETTY_FUNCTION__. However, none of those are standard in C++03. C++11 does standardize __func__, but only as an "implementation-defined string", which isn't guaranteed to be useful, or even unique. On top of that, the values will be different on different compilers. Also, some of them may be macros rather than identifiers, to make things more fun.
If you want truly portable code, in C++11, you can use something like string(__func__) + ":" + STRINGIZE(__LINE__)—this will be somewhat ugly, but at least each function will have a unique name. And in C++03, there is no equivalent. If you just need "portable enough", consult the documentation for every compiler you use, or rely on something like autoconf.
Is there any reason you can't use standard profiling tools that will count these calls for you? Something like gprof?
Otherwise static integers would be the way to go.
Assuming you want these statistics tracked all the time in your program, you could use an unordered_map of your function names:
std::unordered_map<const char *, unsigned> stats;
void foo () {
// use __FUNCDNAME__ for MSVC
++stats[__PRETTY_FUNCTION__];
//...
}
The use of compiler specific function name specifiers is purposefully there to get the decorated function names. This is so that overloaded function names get counted as separate functions.
This technique allows you to add new functions easily without thinking about anything else, but there is a small additional cost if there are hash collisions (which can be remedied somewhat by sizing the stats map to be larger). There is no hash computed on the string, since the key is a pointer type, it just uses the pointer value itself as the hash.
If this is just one-off code for profiling, then you should first try to use the code profiling tools available on your platform.
You can put static locals inside the methods themselves, that seems cleaner since these variables aren't logically connected to the class so there's no reason to make them members.
Additionaly, you could have a macro to simplify the work. I normally don't recommend using macros, but this seems like an appropriate use:
#define DEFINE_COUNTER \
static int noCalls = 0; \
noCalls++;
void foo()
{
DEFINE_COUNTER
}
Use a library that implements the Observer Pattern or Method Call Interception. You can choose one from this list, or use something like Vitamin.

C++ function prototypes?

Here goes newbie question number 5, but I don't have a teacher.. so.. anyhow here we go:
I'm wondering if is necessary to have function prototypes at the top of the file, instead of putting the main function to the end of the file and create all the function at the top of the file. As far as I can tell, VC++ and G++ both are not complaining. Is there standards that disallows me to do so?
It seems rather annoying to have to change the prototype when you change a function parameters and return types.
Example:
#include <iostream>
void say_hi(){
std::cout << "hi" << std::endl;
}
int main(){
say_hi();
return 0;
}
This declares but does not define the function say_hi:
void say_hi();
This both declares and defines the function say_hi:
void say_hi(){
std::cout << "hi" << std::endl;
}
You can declare a function many times; you can only define it once.
A function must be declared in the file before you can call it. A function must be defined somewhere--in the same file before or after you call it or maybe even in a different file.
So, yes, this is perfectly fine.
You are correct; if you define all your functions above where they are called, you don't need function prototypes. The actual function definition serves the same purpose as a separate declaration.
This works when you have tiny functions. It works less well when they get long. Or when you have more than one file of code. As a matter of style, many teachers demand that even tiny applications be written with the structure that serves large applications well.