Different exception specifier with g++ 6.2
Asked Answered
F

2

11

Could someone explain to me why this code doesn't compile with g++ version 6.2.0, but compiles fine with clang++ version 3.9.0-svn274438-1 and icpc version 16.0.2

$ cat wtf.cpp
#include <cstdio>
#include <new>
void *operator new(std::size_t) throw(std::bad_alloc);
void *operator new(std::size_t) throw (std::bad_alloc) { void *p; return p; }

$ g++-6 wtf.cpp -c 
wtf.cpp: In function ‘void* operator new(std::size_t)’:
wtf.cpp:4:7: error: declaration of ‘void* operator new(std::size_t) throw (std::bad_alloc)’ has a different exception specifier
 void *operator new(std::size_t) throw (std::bad_alloc) { void * p; return p; }
       ^~~~~~~~
wtf.cpp:3:7: note: from previous declaration ‘void* operator new(std::size_t)’
 void *operator new(std::size_t) throw(std::bad_alloc);
Fettle answered 28/8, 2016 at 7:23 Comment(0)
B
8

Are you using C++11 or later?

The original operator new() declarations in C++98

throwing:   
void* operator new (std::size_t size) throw (std::bad_alloc);

nothrow:
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) throw();

placement:
void* operator new (std::size_t size, void* ptr) throw();

Have been changed in C++11 to use noexcept keyword:

throwing:   
void* operator new (std::size_t size);

nothrow:    
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;

placement:  
void* operator new (std::size_t size, void* ptr) noexcept;

Reference link.

Bootie answered 28/8, 2016 at 8:0 Comment(2)
By adding -std=c++03, g++ compiles fine. But that doesn't explain why I get this error message, right? Line 3 of wtf.cpp still has the same exception specifier as line 4, I think.Fettle
@Fettle - throw() and noexcept have similar effect, but the throw (std::bad_alloc) is totally different from not specifying the exceptions thrown.Vibrissa
E
1

In GCC 6 the default mode for C++ has changed to C++14. Until GCC 5 it was C++98.

The operator new declaration has changed slightly in C++11. It has to do with the fact that the throwing exception specification is deprecated in C++11, and the introduction of the nothrow declaration:

  • throw (std::bad_alloc) has been omitted
  • throw() is replaced with nothrow

For best backwards-compatibility you should specify which C++ standard you're targeting using the -std argument, like this:

$ g++-6 -std=c++98 wtf.cpp -c 
Earlearla answered 28/8, 2016 at 8:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.