Consider a program consists of files AA.hpp, A1.hpp, A1.cpp, and main.cpp compiled with g++ -std=c++11 main.cpp A1.cpp.
// file AA.hpp
template < int > struct AA;
// file A1.hpp
#include "AA.hpp"
template <> struct AA<1> { /*implementation goes here...*/ };
extern template struct AA<1>;
// file A1.cpp
#include "A1.hpp"
template struct AA<1>;
// file main.cpp
#include "A1.hpp"
int main()
{
AA<1> a1;
// use a1 ...
return 0;
}
Compare this with a scenario when there is no A1.cpp and there is no explicit instantiation declaration in A1.hpp. Will I get any compilation time benefits in the first scenario? And why?
Another question. What if I make a shared library of A1.cpp by g++ -std=c++11 -shared -o libA1.so A1.cpp and then make executable with g++ -std=c++11 -lA1 main.cpp? Will the calls of A1's functions in man.cpp refer to the code in libA1.so or they will be generated (inlined or not) in the executable?
Related
main.cpp
#include <iostream>
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
foo.cpp
#include <iostream>
extern "C" {
void foo() {
std::cout << "bar" << std::endl;
}
}
Compile static library:
$ g++ foo.cpp -static
Error:
undefined reference to `WinMain'
But this compiles:
$ g++ foo.cpp -shared -o foo.lib
Now I have a static library named foo.lib (supposedly).
I try to compile an executable that links to it:
$ g++ -L -lfoo main.cpp -o main.exe
And get this error:
'foo' was not declared in this scope
But foo is declared in the static library that I'm linking with. If the link works, I don't think I need to declare it in main.cpp also. So why isn't the link working?
Update.
I added void foo(); to main.cpp so it doesn't complain that foo needs to be declared.
#include <iostream>
void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
So I try to compile again and I get this new error:
undefined reference to `foo()'
Why would I need to define foo in main.cpp? It's already defined in foo.cpp which is the static library.
If I have to define foo in main.cpp that defeats the entire purpose of linking to the library foo.lib.
UPDATES
Removing all the extern "C" { ... } lines doesn't make the "foo is undefined" errors go away.
What follows are the magical incantations you seek:
main.cpp
#include <iostream>
extern void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
}
foo.cpp
#include <iostream>
void foo() {
std::cout << "bar" << std::endl;
}
Console commands:
$ g++ -o foo.obj -c foo.cpp
$ ar rcs foo.lib foo.obj
$ g++ main.cpp foo.lib -o main.exe
These spells conjure up the static lib foo with the executable main statically linked to it.
i have this simple code in the following files:
Stat.h
#ifndef STAT_H
#define STAT_H
class Stat {
public:
void compute_value();
};
#endif
Stat.cpp
class Stat {
public:
void compute_value() {
}
};
main.cpp
#include "Stat.h"
int main(void)
{
Stat stat;
stat.compute_value();
}
When i try to compile i got the following error:
clang++ -std=c++14 -Wall -Wextra -pedantic -Weverything -O3 Stat.cpp main.cpp -o main
/tmp/main-0466d7.o: In function `main':
main.cpp:(.text+0xf6a): undefined reference to `Stat::compute_value()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You are redefining the class in your Stat.cpp source file because definition is also a declaration. Instead of having the entire class redefinition you only need to define the member function(s) in your Stat.cpp source file and include the Stat.h header:
#include "Stat.h"
void Stat::compute_value() {}
I have a lib which I want to test using google test framework. The code is very old and I can't change anything in actual code.
I have included a header file first.h which have following typedef:
typedef struct aList* aList;
and in another file, say second.c, struct is defined as:
struct aList {
aRecord* top;
};
and in my TestFile.cc:
#include "gtest/gtest.h"
#include "First.h"
TEST(First_Test, Create)
{
FuncName();
}
when I compile it using:
g++ -isystem ../../../test/framework/gtest/googletest/include -isystem ../../../test/framework/gtest/googlemock/include -g -Wall -Wextra -pthread --coverage -Iinclude/path -c TestFile.cc -Lpath/to/lib -llibfile
I get following error:
error: conflicting declaration typedef struct aList* aList
error: struct aList has a previous declaration as struct aList
There are no include guards in header files. But I don't think issue is because of that.
Any clue how to fix this?
EDIT
Here is a complete verifiable example.
Contents of FirstFile.h:
#include "SecondFile.h"
typedef struct aList* aList;
void func();
Contents of FirstFile.c:
#include "FirstFile.h"
void func()
{
}
void main()
{
func();
}
Contents of SecondFile.h:
struct aList {
int* top;
};
Contents of TestCode.cc:
#include "FirstFile.h"
void funcTest()
{
func();
}
Command to compile:
g++ TestCode.cc -o TestCode
unfortunately some little devil in your company has managed to get non-conforming c++ code into your libraries.
Simply trying to compile this:
struct aList {};
typedef struct aList* aList;
results in:
2 : error: conflicting declaration 'typedef struct aList* aList'
typedef struct aList* aList;
^
1 : note: previous declaration as 'struct aList'
struct aList {};
I am afraid you are compelled to fix the faulty library.
I am trying to get a template code working with the header file and cpp file separated. I use explicit instantiation for this. But I still get an undefined reference error.
foo.h
template<typename T>
class Foo
{
public:
void f();
};
foo.cc
#include <iostream>
#include "Foo.h"
template<typename T>
void Foo<T>::f()
{
std::cout << "Foo<T>::f()\n";
}
template class Foo<int>;
main.cc
#include "foo.h"
int main()
{
Foo<int> x;
x.f();
}
When I compile:
g++ main.cc -o test
/tmp/ccfHjiVJ.o: In function `main':
main.cc:(.text+0x10): undefined reference to `Foo<int>::f()'
collect2: ld returned 1 exit status
The gcc version I use is gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
You've forgotten to compile foo.cc in your compile command, add foo.cc:
g++ main.cc foo.cc -o test
^^^^^^
class.h
#include <iostream>
#include <stdint.h>
using namespace std;
template <typename T>
class CIntegerType {
public:
void Show ( void );
private:
T m_Data;
};
class.cpp
#include "class.h"
template <typename T>
void CIntegerType<T> :: Show ( void ) {
cout << m_Data << endl;
}
main.cpp
#include "class.h"
int main ( void ) {
CIntegerType<uint32_t> UINT32;
UINT32 . Show ();
return 0;
}
This commands return:
g++ -Wall -pedantic -c main.cpp
g++ -Wall -pedantic -c class.cpp
g++ -Wall -pedantic -o class.o main.o
main.o: In function `main':
main.cpp:(.text+0x11): undefined reference to 'CIntegerType< unsigned int>::Show()'
collect2: ld returned 1 exit status
Try putting your template implementation in the header file.
See: Why can templates only be implemented in the header file?
Try g++ -Wall -pedantic -o main.o class.o instead. You are facing the same problem as in this question: g++ linking order dependency when linking c code to c++ code
The linker searches for functions in the order they appear. Since you have a template function, its use in main must be fed to the linker prior to the actual code to instantiate it in class.