Following code not compiling:
A.h
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
namespace net {
using Ip = in_addr_t;
using Port = in_port_t;
using SockFd = int;
class Params final {
public:
Ip getIp() const { return ip_; }
Port getPort() const { return port_; }
private:
Ip ip_ {INADDR_ANY};
Port port_ {htons(5)};
};
}
A.cpp
#include <iostream>
#include "A.h"
int main(){
net::Params a {};
std::cout << "Ip=" << a.getIp() << ", Port=" << a.getPort() << std::endl;
return 0;
}
Compilation:
g++-6 -O2 -std=c++11 A.cpp
Error:
In file included from /usr/include/x86_64-linux-gnu/bits/byteswap.h:35:0,
from /usr/include/endian.h:60,
from /usr/include/ctype.h:39,
from /usr/include/c++/6/cctype:42,
from /usr/include/c++/6/bits/localefwd.h:42,
from /usr/include/c++/6/ios:41,
from /usr/include/c++/6/ostream:38,
from /usr/include/c++/6/iostream:39,
from A.cpp:1:
A.h:21:15: error: statement-expressions are not allowed outside functions nor in template-argument lists
Port port_ {htons(5)};
^
In file included from A.cpp:3:0:
A.h:21:23: error: cannot convert ‘<brace-enclosed initializer list>’ to ‘net::Port {aka short unsigned int}’ in initialization
Port port_ {htons(5)};
^
But when I change port_ member variable initialization to: Port port_ {5};, g++ with -O2 compiles fine.
Above code compiles fine without optimization flag, whether port_ initialized as: Port port_ {htons(5)}; or as Port port_ {5};
Whats wrong?
Seems to be a ompiler and/or libstd bug. The compiler tries to optimize away the function call to htons with some macros and compiler magic. That results in some problem I do not understand. But you can define an inline function myhtons that calls htons and use that instead. Works for me with gcc 7.2.
inline Port myhtons( Port v )
{
return htons(v);
}
class Params final {
public:
Ip getIp() const { return ip_; }
Port getPort() const { return port_; }
private:
Ip ip_ {INADDR_ANY};
Port port_ { myhtons(5) };
};
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
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 struggling with g++ compilation over c++.11
Here is the problem I'm facing:
error: 'IGameController' does not name a type.
The IGameController is actually my class interface, where I've put the location on my g++ script.
Here it is my g++ script to compile:
cd C:\MinGW\bin\
g++ -std=c++11 -c c:\Users\me\Downloads\TheGame\TheGame.cpp
g++ -std=c++11 -Ic:\Users\me\Downloads\TheGame\GameController\inc -Ic:\Users\me\Downloads\TheGame\GameController\src -c c:\Users\me\Downloads\TheGame\GameController\src\GameController.cpp
g++ -std=c++11 -o c:\Users\me\Downloads\TheGame\TheGame.exe *.o
I don't understand why the script doesn't find my header files...
My project is structured like this:
TheGame\TheGame.cpp
TheGame\GameController\inc\GameControllerProvider.hpp
TheGame\GameController\inc\IGameController.hpp
TheGame\GameController\src\GameController.cpp
TheGame\GameController\src\GameController.hpp
Here is my source code:
[TheGame.cpp]
#include <iostream>
#include "GameController/inc/GameControllerProvider.hpp"
#include "GameController/inc/IGameController.hpp"
int main()
{
GameController::IGameController& gameController = GameController::GameControllerProvider::getGameController();
gameController.printSomething();
return 0;
}
[IGameController.hpp]
#pragma once
namespace GameController
{
class IGameController
{
public:
virtual void printSomething() = 0;
protected:
IGameController() {}
virtual ~IGameController() {}
};
}
[GameControllerProvider.hpp]
#pragma once
namespace GameController { class IGameController; }
namespace GameController
{
namespace GameControllerProvider
{
IGameController& getGameController();
}
}
[GameController.hpp]
#pragma once
#include "GameController/inc/IGameController.hpp"
namespace GameController
{
class GameController : public IGameController
{
public:
GameController();
virtual ~GameController();
void printSomething() override;
private:
};
}
[GameController.cpp]
#include <iostream>
#include "GameController/inc/IGameController.hpp"
#include "GameController/src/GameController.hpp"
#include "GameController/inc/GameControllerProvider.hpp"
namespace GameController
{
GameController::GameController() {}
GameController::~GameController(){}
void GameController::printSomething()
{
std::cout << "printSomething()" << std::endl;
}
}
// Provider
IGameController& GameControllerProvider::getGameController()
{
static GameController sGameController;
return sGameController;
}
}
I'm not familiar with namespaces, but for sure one of your problems is with the #include statements, where you give a wrong path to some files.
For instance, when you call IGameController.hpp (in inc/) from GameController.cpp (in src/), since you are using quoations marks (" "), you should give the full path to the file, and it should be written as:
#include "../inc/IGameController.hpp"
Hope it helps.
I'm trying to make C-string size calculation at compile time, using code like this:
#include <stdio.h>
#include <stdint.h>
class StringRef
{
public:
template<int N>
constexpr StringRef(const char (&str)[N])
: m_ptr(str), m_size(uint32_t(N-1)) {}
constexpr const char *constData() const
{ return m_ptr; }
private:
const char *m_ptr;
uint32_t m_size;
};
struct S
{
StringRef str;
};
constexpr static const struct S list[] =
{
"str",
};
int main()
{
printf("%s\n", list[0].str.constData());
return 0;
}
In clang-3.7 everything is fine, but in GCC 4.9.3-5.3 I get:
error: could not convert '(const char*)"str"' from 'const char*' to
'StringRef'
It can be fixed by adding explicit braces:
constexpr static const struct S list[] =
{{
{ "str" },
}};
But code became ugly and, still, clang somehow understand it correctly.
How can I make gcc understand array initialization without explicit braces?
I am trying to create Google Mock object for some interface class which uses boost::variant
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <boost/variant.hpp>
#include <vector>
typedef std::vector<int> VectorOfInt;
typedef boost::variant<VectorOfInt> VariantOfVector;
class InterfaceClass
{
public:
virtual ~InterfaceClass() {}
virtual void SetSome( const VariantOfVector& ) = 0;
virtual const VariantOfVector& GetSome() const = 0;
};
class MockInterfaceClass
{
public:
MOCK_METHOD1( SetSome, void( const VariantOfVector& ) );
MOCK_CONST_METHOD0( GetSome, const VariantOfVector&() );
};
When I compile it with
g++ mytest.cpp -o mytest
i get
/usr/include/boost/variant/detail/variant_io.hpp:64: error: no match for ‘operator<<’ in ‘((const boost::detail::variant::printer > >*)this)->boost::detail::variant::printer > >::out_ << operand’
Does boost::variant work with std::vector? It seems boost::variant works with any type I define but std:vector. Why?
Boost version - 1.45
g++ version - 4.4.5
It seems that the mock attempts to apply operator << to your variant. You have to define operator << for its contents, i.e. for std::vector template.
As Igor R. answered, you need to add operator << (without namespace) like this:
std::ostream& operator <<(std::ostream& out, VariantOfVector const& rhs)
{
//Print or apply your visitor to **rhs**
return out;
}