Will extern template reduce the compile time for a full specialization? - c++

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

How to write a static C++ library and link it to an executable using g++ on Windows 10?

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.

failed to link simple code

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() {}

error: conflicting declaration. compiling c code with g++

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.

Error Even after Explicit Instatantiation

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
^^^^^^

C++ linking object's files (G++)

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.