I would like to ask a question about the output when I called an inline function, that was declared inside MyHeader.h, which was defined in both source_1.cpp and source_2.cpp files, using the int main() function inside source_2.cppfile.
When I do such a call, the one defined inside the source_1.cpp function is called. The codes are like;
My MyHeader.h contains the following line of codes:
#pragma once
#include <iostream>
inline int func(void);
My source_1.cpp contains the following line of codes:
#include "MyHeader.h"
int func(void)
{
std::cout << "func(), inside source_1, was called. 102 * 102 will be returned." << "\n";
return 102 * 102;
}
void source_1(void)
{
std::cout << "source_1() was called. func() will be called." << "\n";
func();
}
My source_2.cpp contains the following line of codes:
#include "MyHeader.h"
int func(void)
{
std::cout << "func(), inside source_2, was called. 102 * 102 will be returned." << "\n";
return 102 * 102;
}
void source_2(void)
{
std::cout << "source_2() was called. func() will be called." << "\n";
func();
}
int main()
{
std::cout << "main() was called." << "\n";
source_2();
}
This is the output:
main() was called.
source_2() was called. func() will be called.
func(), inside source_1, was called. 102*102 will be returned.
I wish to know the reason.
You violated the one definition rule. You are not permitted to have non-static objects in your program with different implementations. The compiler/linker is free to choose any implementation it finds, which can lead to very hard to find bugs.
Your source_2 function called func function of source_1.cpp because func is declared as inline , not static . When the linker gets a inline function, it remove all copies of that function except one. So the func function of source_1.cpp is kept, other one is removed by the linker. If you want to have two separate implementation of one function in two source file, declare the function as static . This prevents the linker from removing multiple functions of same name.
Related
I just got a sample of code, which cannot be modified:
#include <iostream>
#include "Image.h"
#include "Ppm.h"
int main() {
Image* ob = 0x0;
try
{
ob = new Ppm("lena.ppm");
long kolor = countColors(*ob);
std::cout << "Unikalnych kolorow: " << kolor << '\n';
}
catch (ImageError& e)
{
std::cout << e.what() << std::endl;
}
delete ob;
return 0;
}
I am confused with line
long kolor = countColors(*ob);
Two questions:
1) should this function be static?
2) should it be in class Image, or in Ppm, which inherit from the first one?
I am confused with line
long kolor = countColors(*ob);
You say that the code cannot be modified, so this line is already there in the code, and I assume the code is compiling/linking OK?
If it compiles OK, the function declaration for countColors() must be getting included from either from Image.h or Ppm.h, or from a header file that one of them includes. It certainly isn't coming from iostream.
If it's linking successfully, the object file or library containing the function definition for countColors() must be getting included in the link step.
We can only guess at the signature of this function; something like:
long countColors(const Ppm& portablePixmap);
...or maybe...
long countColors(const Image& image);
Whatever the signature is, it would not be declared with the keyword static (outside of a class), unless it was only used in the same file it's implemented in.
1) should this function be static?
The short answer is: it's unlikely that it is declared as static (see why below), but that's probably not what you're really asking about.
We know countColors() isn't a class method or instance method, because if it were, you'd have to call it like this1:
long kolor = SomeClass::countColors(*ob); // (class method)
or
long kolor = some_instance.countColors(*ob); // (instance method)
So if it's not a class or instance method, is it static? Probably not; here's why:
Say you've defined a function foo in file foo.c:
void foo(void) { ... }
...you can call it from bar.c:
#include "foo.h" // Tells compiler about foo()
void bar() { foo(); } // COMPILES AND LINKS OK
...but if you had defined the function in foo.c using the static keyword:
static void foo(void) { ... }
...the linker treats it as private to foo.c, so you can't call it from bar.c or any other source file besides foo.c:
#include "foo.h" // Tells compiler about foo()
void bar() { foo(); } // COMPILE OK, BUT LINKER ERROR!
2) should it be in class Image, or in Ppm, which inherit from the first one?
'should' implies that you're looking for the right place to put this method, but you also stated that this code can't be modified.
Are you trying to call this method from your own code, and you're not sure which header file to include, or how to call it?
Sorry, I could give you a better answer if I understood what it was you wanted to do.
1 It's possible to do evil things with macros in C/C++ like #define countColors(x) SomeClass::countColors(x), but we'll ignore that possibility.
For my homework, this is my assignment:
Create 5 files. Driver.cpp, f.h, f.cpp, g.h, g.cpp. f and g should implement a function called hello. Driver should
call hello from f and g.
Example Output:
hello from f
hello from g
Press any key to continue . . .
I have all these files created, but what I dont understand is how can the same function hello() exist in two files and be called from the driver.cpp file? any help would be greatly appreciated!
edit: The error I get is "fatal error LNK1169: one or more multiply defined symbols found". This is referring to the two hello() functions. How do I fix this?
Globally visible entities are allowed to have only one definition. Thus, you can't have the same function hello() defined in multiple translation units. There are a few separate approaches how to define equally named functions multiple times:
Overloaded function can have the same name as long as they differ in their arguments in some way. For example, you could have each of the hello() functions take an argument which differs between the different versions (note: I'm not suggesting this approch). For example:
void hello(bool) { std::cout << "hello(bool)\n"; }
void hello(int) { std::cout << "hello(int)\n"; }
You can define the names in different namespaces. This makes the fully qualified name actually different, i.e., the conflict is prevented by just using a different scope, e.g.:
namespace a { void hello() { std::cout << "a::hello()\n"; }
namespace b { void hello() { std::cout << "b::hello()\n"; }
Assuming you call your function from a function in the local file, you can move the function from being globally visible to being only locally visible using the static keyword. Functions with local visibility do not conflict between different translation units. For example:
// file a.cpp
static void hello() { std::cout << "a.cpp:hello()\n"; }
void a() { hello(); }
// file b.cpp
static void hello() { std::cout << "b.cpp:hello()\n"; }
void b() { hello(); }
Which of these versions your teach is actually after, I don't know. Each one has their use, though, and it is useful to know the different variations.
In case someone claims that for completeness I should have included virtual functions: note that overriding a function is actually also creating an overload (the virtual function in the base and the overriding function differ in the implicity passed object), i.e., the use of virtual functions is already covered.
You should use namespaces :
In f.h
:
namespace mynamespace {
void hello();
}
In f.cpp
void mynamespace::hello()
{
/... function definition here
}
In main()
int main()
{
mynamespace :: hello(); // calls hello defined in f.cpp
}
For a good introduction to namespaces. Namespaces
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
C++: Easiest way to access main variable from function?
I need to get my variable "input" from my main function in a.cpp to another function named check in b.cpp. I looked into it on Google and this forum/thingy, and I found you could do it with global variables using extern, but that's it's also bad to use those and I couldn't find an answer to what an alternative is? How should I transfer the data in the variable to the other function without using globals?
Code of how I got arguments to work.
(What I'm trying to do here is a console "manager" for solutions of project Euler which I can call to solve/view via input, I started working on the code 40 mins ago.)
main.cpp
#include <iostream>
#include <windows.h>
#include "prob.h"
using namespace std;
int check(string x);
int main()
{
string input = "empty";
clear();
cout << "Welcome to the Apeture Labs Project Euler Console! (ALPEC)" << endl << endl;
cout << "We remind you that ALPEC will never threaten to stab you" << endl;
cout << "and, in fact, cannot speak. In the event that ALPEC does speak, " << endl;
cout << "we urge you to disregard its advice." << endl << endl;
cin >> input;
cin.get();
check(input);
cout << input << endl;
cin.get();
return 0;
}
prob.h
#ifndef PROB_H_INCLUDED
#define PROB_H_INCLUDED
int main();
int clear();
int check();
int back();
int P1();
int P2();
int P3();
int P4();
#endif // PROB_H_INCLUDED
back.cpp
#include <iostream>
#include <windows.h>
#include "prob.h"
using namespace std;
int clear()
{
system( "#echo off" );
system( "color 09" );
system( "cls" );
return 0;
}
int check( string x )
{
if( x == "help" );
if( x == "empty" )
{
cout << "And.... You didn't enter anything..." << endl << endl;
}
else
{
cout << "Do you have any clue what you are doing? " << endl << endl;
}
return 0;
}
By passing the data as an function argument.
For example:
int doSomething(int passedVar)
{
}
int main()
{
int i = 10;
doSomething(i);
return 0;
}
Note that the function definition may reside even in a different cpp file. The main only needs to see the function declaration, and the linker shall link the function definition correctly.
Usually, one would add the function declaration in a header file and include the header file in main, while providing the function definition in another cpp file.
The code you show has number of problems:
You do not need to declare main in the header file.
Your function declaration and definition of check() do not match. Your header file says it takes no argument and you define a the function definition to take one argument. Obviously, they don't match. As they stand now they are two completely different functions.
As the compiler sees it you declared one function who's definition you never provided and you defined another function in the cpp file. Thus the function declared(one with no parameters) was never defined and hence the definition not found error.
Andrei Tita is absolutely correct. If you have a "value" in one module (e.g. "main()" in a.cpp), and you wish to use that value in a function (e.g. "foo()" in b.cpp) ... then just pass that value as a function argument!
As your programs become more sophisticated, you'll probably start using classes (instead of functions) .
This is a small program :
#include <iostream>
using namespace std;
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
The error that i get here is :error C3861: 'f': identifier not found
If i place the function f above main I will get the desired output.
Why it is so ?
I was told that program execution begins at main. According to this the code should run in the first case also.
How does the compiler start reading the program?
The beginning of the compilation and the beginning of the execution of the program are two different things.
The execution starts from the main.
The compilation begins from the beginning of the file; the compiler don't "jump around" the file to find the needed pieces, but it reads the input in a linear fashion (I suspect that this related, among the other things, to the fact that the C++ grammar is really complicated).
When the compiler is at some point in parsing the file, it only knows what has been declared/defined up to that point1.
Because of this, function prototypes (and non-defining declarations in general) have been invented: the prototypes of all the functions defined in the file are put at the beginning of the file, typically after the #include directives or in a separated include file. The prototypes tell to the compiler that such functions will be defined later, and what is the function signature (i.e. name, parameters, return value).
The prototype is made as a normal function, but without the body, which is replaced by a semicolon2. For example, in your code you would write
void f();
before the main.
IIRC there are some relaxations to this rule that allow the compiler to "wait" for some declarations to make some template magic work, but this is not relevant here.
In a prototype is also common not to write the names of the parameters, leaving just their type (this can be done also in function definitions, but it doesn't make much sense there unless you have a formal parameter you don't use). Still, I prefer to leave the parameter names there as a form of documentation.
I was told that program execution begins at main.
And that's exactly the point.
The compiler starts from main, and then sees a call to f(), which it has not encountered so far (as it is defined afterwards), so it does not know what to do with it.
If you want to define f after main you can place a function prototype before, such as
#include <iostream>
using namespace std;
void f(); // <--- This tells the compiler that a function name f will be defined
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
To be able to call a function it must have been declared at some earlier point in the code. This is just a rule of the language designed to help compilers.
You can declare the function earlier with e.g.
void f();
...and then define it after main as you have done.
The compiler starts at the top and reads down to the bottom.
you'll need to have something like:
#include <iostream>
using namespace std;
void f();
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
No, the compiler needs to see at least a declaration of f() before it is used. A c(++) code file is a simple text file and must be read from begin to end by the compiler.
During the compilation process, when the compiler is evaluating main() it needs to know what f() is in advance to be able to generate the correct assembly code to call this function. That's why you need to put it before main() in this case.
As an alternative you can declare the prototype of f() before main() so the compiler knows it's a local function declared somewhere else on your file:
void f(); // prototype
int main()
{
// .. code ..
}
void f() // implementation of f()
{
// .. code ..
}
Playing around with MSVC++ 2005, I noticed that if the same class is defined several times, the program still happily links, even at the highest warning level. I find it surprising, how comes this is not an error?
module_a.cpp:
#include <iostream>
struct Foo {
const char * Bar() { return "MODULE_A"; }
};
void TestA() { std::cout << "TestA: " << Foo().Bar() << std::endl; }
module_b.cpp:
#include <iostream>
struct Foo {
const char * Bar() { return "MODULE_B"; }
};
void TestB() { std::cout << "TestB: " << Foo().Bar() << std::endl; }
main.cpp:
void TestA();
void TestB();
int main() {
TestA();
TestB();
}
And the output is:
TestA: MODULE_A
TestB: MODULE_A
It is an error - the code breaks the C++ One Definition Rule. If you do that, the standard says you get undefined behaviour.
The code links, because if you had:
struct Foo {
const char * Bar() { return "MODULE_B"; }
};
in both modules there would NOT be a ODR violation - after all, this is basically what #including a header does. The violation comes because your definitions are different ( the other one contains the string "MODULE_A") but there is no way for the linker (which just looks at class/function names) to detect this.
The compiler might consider that the object is useless besides its use in Test#() function and hence inlines the whole thing. That way, the linker would never see that either class even existed ! Just an idea, though.
Or somehow, linking between TestA and class Foo[#] would be done inside compilation. There would be a conflict if linker was looking for class Foo (multiple definition), but the linker simply does not look for it !
Do you have linking errors if compiling in debug mode with no optimizations enabled ?