I'm using gcc-4.7.1 on windows 8 Release Preview with git-bash.
$ g++ -v
Using built-in specs.
COLLECT_GCC=c:\Users\nikhil bhardwaj\mingw64\bin\g++.exe
COLLECT_LTO_WRAPPER=c:/users/nikhil bhardwaj/mingw64/bin/../libexec/gcc/x86_64-w
64-mingw32/4.7.1/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: /home/drangon/work/mingw-w64-dgn/source/gcc/configure --host=x8
6_64-w64-mingw32 --target=x86_64-w64-mingw32 --disable-nls --enable-languages=c,
c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn/build/for_target --
enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/hom
e/drangon/work/mingw-w64-dgn/target --with-sysroot=/home/drangon/work/mingw-w64-
dgn/target
Thread model: win32
gcc version 4.7.1 20120524 (prerelease) (GCC)
When I try to compile a small code snippet,
using namespace std;
struct node
{
int data;
node *left, *right;
};
node *newNode(int data)
{
node *node = new (struct node);
node->data = data;
node->left = nullptr;
node->right = NULL;
return node;
}
I get this error,
$ g++ -I../includes bst.cpp
bst.cpp: In function 'node* newNode(int)':
bst.cpp:13:18: error: 'nullptr' was not declared in this sc
bst.cpp:14:19: error: 'NULL' was not declared in this scope
I'm not able to use either NULL or nullptr, do I need to include some header files?
Try in c++11 mode:
g++ -std=c++11 -I../includes bst.cpp
Related
I accidentally removed a const qualifier from a derived class implementation of a virtual method. I usually use clang which issues a warning about that. When I switched to gcc with Wall the thing goes completely unnoticed. Why is that? Here is my file:
$ cat main.cpp
#include <iostream>
class Father {
public:
virtual int get() const { return 8; }
};
class Son : public Father {
public:
virtual int get() /* const */ { return 6; }
};
int main(int argc, char **argv)
{
Father *f = new Son;
std::cout << f->get() << "\n";
return 0;
}
And here are the compilation outputs for gcc and clang:
$ clang++ -Wall main.cpp -o main
main.cpp:10:14: warning: 'Son::get' hides overloaded virtual function
[-Woverloaded-virtual]
virtual int get() /* const */ { return 6; }
^
main.cpp:5:14: note: hidden overloaded virtual function 'Father::get' declared
here: different qualifiers ('const' vs unqualified)
virtual int get() const { return 8; }
^
1 warning generated.
And
$ g++ -Wall main.cpp -o main
$ ./main
8
Or at least I think it is.
Consider the following code
#include <iostream>
#include <memory>
struct BaseBase {
virtual void foo() = 0;
virtual ~BaseBase(){}
};
template <typename Derived>
struct Base : BaseBase{
void foo() override{
static_cast<Derived*>(this)->foo();
}
};
struct D1 : Base<D1> {};
struct Unrelated {};
// no runtime polymorphism
template <typename SDerived>
struct SBase{
void foo() {
static_cast<SDerived*>(this)->foo();
}
};
struct SD1 : SBase<SD1> {};
template <typename T, typename ...Args>
void doFoo(Args&&... args){
T* t = new T(std::forward<Args>(args)...);
t->foo();
}
int main(){
doFoo<Unrelated>(); //compile time error, foo not found in unrelated
doFoo<SD1>(); //runtime crash
doFoo<D1>(); //runtime crash
return 0;
}
I was hoping the compiler would be nice enough to check for the existence of fooat compile time in doFoo but in both cases, with virtual in base, and without virtual in base the code compiles just fine but crashes at runtime.
Why is this?
Edit: clang setup
clang version 4.0.1 (tags/RELEASE_401/final)
Target: x86_64-unknown-linux-gnu
with doFoo<Unrelated>() commented out compiles.
and g++ setup
gcc version 7.1.1 20170630 (GCC)
compiles with doFoo<Unrelated>() commented out.
This is because both of the classes have a function called foo. It's present in the base class for each class.
However, all that function does is call itself, which will eventually result in a stack overflow.
My gcc version is 4.8.5
posix gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
I have two cpp files:
1.cpp and 2.cpp
while there is a static function in 1.cpp called by 2.cpp。
In most machine,we should like this:
g++ 2.cpp 1.cpp
or it will cause compile error or runtime error。
However,in my machine with gcc 4.8.5,I must compile using “g++ 1.cpp 2.cpp” to make it run successful。
Is this the property of gcc4.8.5? or there is something wrong on my soft,or I used it wrong?
==============================================================
My machine is centos7 installed on virtulbox of mac. Here is my code:
1.h
#include <map>
using namespace std;
class A {
private:
A();
static A _instance;
map<int, int> test_map;
public:
static A& get_instance();
static void fun();
};
1.cpp
#include <iostream>
#include "1.h"
using namespace std;
A A::_instance;
A::A() {
cout << "A::A()\n";
}
A& A::get_instance() {
cout << "A::get_instance()\n";
return A::_instance;
// static A instance;
// return instance;
}
void A::fun() {
cout << "A::fun()\n";
get_instance().test_map[1];
}
main.cpp
#include <iostream>
#include "1.h"
using namespace std;
int test() {
cout << "test()\n";
A::fun();
return 0;
}
int y = test();
int main() {
cout << "main()\n";
A::fun();
}
In most machine and in what I see in the web, we should compile like this:
g++ main.cpp 1.cpp
But in my machine, I must compile like this:
g++ 1.cpp main.cpp
what's wrong with my machine or my gcc?
I think you are facing the static initialization order fiasco which is a classical C++ bug. If initialization function test() in main.cpp is called before constructor for A::_instance has been called, your code will access uninitialized A::_instance::test_map field which is likely to cause segmentation fault. I suggest you rewrite getInstance to create instance when needed:
A *A::_instance;
A& A::get_instance() {
cout << "A::get_instance()\n";
if(!_instance)
_instance = new A;
return *A::_instance;
}
As a side note, I suggest you to use AddressSanitizer to autodetect this and similar types of errors.
I'm working on a program right now and to test template classes (which I will need) I wrote a small (and buggy, chances are 2 or 3 logic bugs in it, my goal is to get it to compile) stack class. What I want to do is to compile it to a static library (.a) then link it with the main program.
The error is:
main.cpp:(.text+0x1c): undefined reference to `Stack<int>::Stack()'
main.cpp:(.text+0x31): undefined reference to `Stack<int>::push(int)'
main.cpp:(.text+0x42): undefined reference to `Stack<int>::push(int)'
main.cpp:(.text+0x4e): undefined reference to `Stack<int>::pop()'
main.cpp:(.text+0x5d): undefined reference to `Stack<int>::pop()'
collect2: error: ld returned 1 exit status
This is the header file:
/* stack.h */
#ifndef _STACK_INCLUDED_
#define _STACK_INCLUDED_
template<typename T>
struct Node
{
T* node;
Node<T>* next;
};
template<typename T>
class Stack
{
private:
Node<T>* bottom;
public:
Stack();
Stack(T first);
Stack(T* arr, int amount);
void push(T push);
T* pop();
};
/* I added the following prototypes in an attempt to correct the error,
did not work*/
template<typename T>
Stack<T>::Stack();
template<typename T>
Stack<T>::Stack(T first);
template<typename T>
Stack<T>::Stack(T* arr, int amount);
template<typename T>
void Stack<T>::push(T push);
template<typename T>
T* Stack<T>::pop();
#endif
Here is the implementation file:
/* stack.cpp */
#include "../heads/stack.h"
#define null (void*)0
template<typename T>
Stack<T>::Stack() {
bottom = null;
}
template<typename T>
Stack<T>::Stack(T first) {
push(first);
}
template<typename T>
Stack<T>::Stack(T* arr, int amount)
{
int i;
for(i=0;i<amount; i++)
{
push(arr[i]);
}
}
template<typename T>
void Stack<T>::push(T push)
{
Node<T>* tmp = new Node<T>();
tmp->node = push;
tmp->next = null;
Node<T>* node = bottom;
while(node->next != null)
{
node = node->next;
}
node->next = tmp;
}
template<typename T>
T* Stack<T>::pop()
{
int i=0;
Node<T>* node = bottom;
while(node->next != null)
{
i++;
node = node->next;
}
node = bottom;
for(;i>1;i++)
{
node = node->next;
}
Node<T>* res = node->next;
node->next = null;
return res->node;
}
You might have noticed the header file is included: "../heads/stack.h", this is because the structure looks like so:
- root
-- CLASSNAME
--- implementation of CLASSNAME
-- heads
--- all the headers
-- obj
--- object files (compiled)
--bin
---final output
.
The makefile looks like so:
CC=g++
CFLAGS=-c -fpermissive -Wall
LFLAGS=-llua
OBJ=obj
BIN=bin
HS=heads
all: $(OBJ)/bind.a $(OBJ)/stack.a $(OBJ)/main.o
$(CC) $(LFLAGS) -o $(BIN)/main $(OBJ)/main.o $(OBJ)/bind.a $(OBJ)/stack.a
$(OBJ)/bind.o: binds/bind.cpp $(HS)/bind.h
$(CC) $(CFLAGS) binds/bind.cpp -o $(OBJ)/bind.o
$(OBJ)/bind.a: $(OBJ)/bind.o
ar -cvq $(OBJ)/bind.a $(OBJ)/bind.o
$(OBJ)/main.o:
$(CC) $(CFLAGS) main/main.cpp -o $(OBJ)/main.o
$(OBJ)/stack.o: $(HS)/stack.h stack/stack.cpp
$(CC) $(CFLAGS) stack/stack.cpp -o $(OBJ)/stack.o
$(OBJ)/stack.a: $(OBJ)/stack.o
ar -cvq $(OBJ)/stack.a $(OBJ)/stack.o
clean:
touch $(OBJ)/dummy
rm $(OBJ)/*
Compiler: g++ 4.7.2 (gcc-multilib)
OS: Arch Linux (x86_64) (kernel 3.6.6-1)
You can get the whole file here (I'm doing multiple test, so don't mind the -llua flag and other files, you can change the Makefile if needed, I just want to figure this out).
After some research and testing, I noticed that the symbols aren't being exported, (nm obj/stack.o shows nothing, while nm obj/bind.o does. same thing for (.a)).
However I could not find any reference to what to do in this case.
You can't make a lib for every possible template parameters, but you can for some types.
A templated class is used to generate code of a class that taking the given type.
When there is a instance using it, it will generate the actual class, otherwise, it will be simply omitted when compile.
According to Compile header-only template library into a shared library? this is possible by using Explicit Instantiation, and make the types you declared into the lib, and let the rest to generate in compile.
I have a function which when compiled using gcc works fine, but when I compile it with g++, it gives me this error:
bon_io.cpp:In function ‘lruc_item* lruc_pop_or_create_item(lruc*)’:
bon_io.cpp:4751: error: invalid conversion from ‘void*’ to ‘lruc_item*’
Code:
typedef struct {
void *value;
void *key;
uint32_t value_length;
uint32_t key_length;
uint64_t access_count;
void *next;
} lruc_item;
lruc_item* lruc_pop_or_create_item(lruc *cache1)
{
lruc_item *item = NULL;
if(cache1->free_items) {
item = cache1->free_items;
cache1->free_items = item->next; [LINE 4751]
} else {
item = (lruc_item *) calloc(sizeof(lruc_item), 1);
}
return item;
}
I am trying to use this function with a c++ code, that's why need to compile it with g++, it works fine if I compile it using gcc but not with g++.
Can anyone please suggest me a way out to make this work with g++ ?
Thanks
How about:
cache1->free_items = (lruc_item *) item->next;
but then why is it that it gets compiled perfectly using gcc and gives
me error with g++
Because in C++ you can't automatically convert from void * to another pointer type.