c++11 static functional member variable - c++

Well, I'm stumped. I've always had a bit of a hard time with static member variables and functions, so if the answer to this is really obvious, I apologize. I can't figure out what's wrong, though.
In WSGrid.h:
#include <functional>
class WSGrid
{
public:
//constructors...
static const std::function< char( void ) > _randomChar;
//private data...
};
In WSGrid.cpp:
#include <random>
std::default_random_engine generator;
std::uniform_int_distribution< char > distribution;
const WSGrid::_randomChar = std::bind( distribution, generator );
In my main.cpp:
#include "WSGrid.h"
#include <iostream>
int main( int argc, char* argv[] )
{
std::cout << WSGrid::_randomChar() << std::endl;
return 0;
}
And when I try to compile (g++ -std=c++11 -Wall -pedantic main.cpp), I get "undefined reference to WSGrid::_randomChar".
So... it looks, to me, like I'm doing everything right. I'm following the syntax found here, at least as far as I'm aware. But apparently there's something wrong.

You need to define _randomChar correctly.
update :
const WSGrid::_randomChar = std::bind( distribution, generator );
to:
const std::function<char(void)> WSGrid::_randomChar = std::bind(distribution, generator);
Also you need to link WSGrid.cpp
g++ -std=c++11 -Wall -pedantic -c WSGrid.cpp -o WSGrid.o
g++ -std=c++11 -Wall -pedantic main.cpp WSGrid.o

Related

Weird things happened when programming in c++20 with fmodules-ts

I have two source files: main.cxx and env.cxx. And main.cxx depends on env.cxx
If I compile them with
c++ -fmodules-ts -std=c++20 -Wall -g env.cxx main.cxx, then everything works well.
But if I compile them with
c++ -fmodules-ts -std=c++20 -Wall -g -c env.cxx
c++ -fmodules-ts -std=c++20 -Wall -g -c main.cxx
c++ -fmodules-ts -std=c++20 -Wall -g env.o main.o
I get segmentation fault.
I do not know whether it is a gcc bug or not, because it works well again if I rewrite them in c++17 style, removing the module declarations.
My compiler is gcc 11.1.0 (The newest version up to now)
Here is env.cxx:
module;
#include <cstdlib>
#include <string>
#include <string_view>
#include <stdexcept>
export module env;
export namespace env
{
std::string get_env(const char* name)
{
char* p = ::getenv(name);
if (p == nullptr)
throw std::runtime_error("environment variable not found");
return std::string(p);
}
// These two functions are useless this time.
std::string get_env(const std::string& name)
{
return get_env(name.data());
}
std::string get_env(std::string_view name)
{
std::string s{name};
return get_env(s.data());
}
}
And main.cxx
module;
#include <iostream>
#include <fstream>
import env;
export module main;
int main(int argc, char** argv)
{
std::cout << env::get_env("HOME") << std::endl;
return 0;
}
Can you reproduce this?
Update 2021.06-19 15:44
In fact the two compiling commands above both work well, and the way that produces segfault is actually:
c++ -fmodules-ts -std=c++20 -Wall -g -c env.cxx
c++ -fmodules-ts -std=c++20 -Wall -g -c main.cxx
c++ -fmodules-ts -std=c++20 -Wall -g main.o env.o
Note that the place of main.o and env.o has been changed.

Why is there uninitialized value in std::normal_distribution

Although the example in std::normal_distribution reference compiled fine, I got a warning on uninitialized value in a similar code below.
#include <random>
void foo(double);
int main()
{
std::default_random_engine generator;
std::normal_distribution<double> norm_dist(0,1);
for(int i=0; i<3; i++)
foo(norm_dist(generator));
return 0;
}
When compiled with "g++ -std=c++11 -Wall -ffast-math -O -c foo.cpp" using gcc5.3.1 on my CentOS7.2, I got:
foo.cpp:8:30: warning:
‘norm_dist.std::normal_distribution::_M_saved’ may be used
uninitialized in this function [-Wmaybe-uninitialized]
foo(norm_dist(generator));
I thought STL had been well tested, but why does the compiler warn? Is the problem in g++, STL, or my code?

Ebpf:undefined symbol for helpers

I run an up to date debian testing (with kernel 4.19).
Helpers are not found on my system (but they exist in the header, Qt jumps to them)
#include "bpf/bpf.h"
int main (){
int r = bpf_create_map(BPF_MAP_TYPE_ARRAY,1,1,1,0);
return 0;
}
Compilation results in
undefined reference to `bpf_create_map(bpf_map_type, int, int, int, unsigned int)'
compiled with
g++ -c -pipe -g -std=gnu++1z -Wall -W -fPIC -DQT_QML_DEBUG -I. -I../../Qt/5.13.0/gcc_64/mkspecs/linux-g++ -o main.o main.cpp
g++ -lbpf -o server main.o
Same result with
g++ main.cpp -lbpf -o out
I have the libbpf-dev installed as well and i have the associated libraries (a and so).
What is wrong?
Update
even the following code won't work
#include <linux/bpf.h>
int main (){
//int r = bpf_create_map(BPF_MAP_TYPE_ARRAY,1,1,1,0);
bpf_attr attr = {};
attr.map_type = BPF_MAP_TYPE_ARRAY;
attr.key_size = 1;
attr.value_size = 1;
attr.max_entries = 1;
bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
return 0;
}
results in
error: 'bpf' was not declared in this scope
Update2:
BTW, key size is mandated to be 4 and not 1; but it is a point aside, that was unrelated to my problem here.
Namespace issue due to compiling in C++, you probably want:
extern "C" {
#include "bpf/bpf.h"
}
int main()...
Regarding your second error (error: 'bpf' was not declared in this scope), this is not directly related to libbpf, this is because there is no function simply called bpf() to actually perform the syscall. Instead you have to use the syscall number. For example, libbpf defines the following:
static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
unsigned int size)
{
return syscall(__NR_bpf, cmd, attr, size);
}
... and uses sys_bpf() after that, the same way you try to call bpf() in your sample.
For the record, “BPF helpers” often designates BPF functions that you call from within a BPF program, which is not the case here. Hence some confusion in the comments, I believe.

Clang reject type_info as incomplete although <typeinfo> is included

I'm lost as to why Clang rejects the following code:
#include <typeinfo>
#include <exception>
const char* get_name( const std::exception_ptr eptr )
{
return eptr.__cxa_exception_type()->name();
}
int main() {}
It OK with GCC, but Clang complains about type_info being an incomplete type:
$ g++-4.7 -std=c++0x -O3 -Wall -Wextra t.cc -o t
$ clang++-3.2 -std=c++0x -O3 -Wall -Wextra t.cc -o t
t.cc:6:37: error: member access into incomplete type 'const class type_info'
return eptr.__cxa_exception_type()->name();
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/exception_ptr.h:144:19: note: forward declaration of
'std::__exception_ptr::type_info'
const class type_info*
^
1 error generated.
$
Question: How do I fix it with Clang? Or am I missing something and Clang is right to reject the code?
Thanks to #HowardHinnant's comment, I managed to fix the problem. The problem became obvious in the preprocessor output: libstdc++ includes <exception> from <type_info> before it even declared std::type_info. That made Clang assume a new forward-declaration std::__exception_ptr::type_info. The solution is as simple as it is illegal:
namespace std { class type_info; }
#include <typeinfo>
#include <exception>
const char* get_name( const std::exception_ptr eptr )
{
return eptr.__cxa_exception_type()->name();
}
int main() {}
Seems like I should check if libstdc++ already has a bug report for that and, if not, create one.
UPDATE: Bug #56468 is now fixed for GCC 4.7.3+

Backtrace on sh4-linux returns one function

I'm trying to print call stack from within a program. Unfortunately, call to glibc backtrace() returns me always only one record - address of current function. I'm working on sh4-linux, which probably causes the problem. I had no problems in printing it on x86 architecture.
Example code:
#include <string>
#include <iostream>
#include <execinfo.h>
const int maxCalls = 666;
void baz()
{
void *buffer[ maxCalls ];
int stackSize = backtrace( buffer, maxCalls );
char **symbols = backtrace_symbols( buffer, stackSize );
std::string str;
for( unsigned i = 0; i < stackSize; ++i )
{
str+= symbols[i];
}
free( symbols );
std::cout << str<< std::endl;
}
void bar()
{
baz();
}
void foo()
{
bar();
}
int main(int argc, char **argv)
{
foo();
return 0;
}
which was compiled by:
sh4-linux-g++ test.cpp -g -c -o test.o
sh4-linux-g++ test.o -g -rdynamic -o test
EDIT: Actually this code works fine. Probably some compiler flag causes this behavior in real project.
Compiler flags are: -g -O0 -pipe -fpermissive -frtti -fno-exceptions -ffunction-sections
Linker flags: -lpthread -g -rdynamic -Wl,-gc-sections -Wl,--start-group {Files here} -Wl,--end-group --verbose -Xlinker -lm
EDIT2: I found out which flag is the cause: -fno-exceptions. Can anyone tell me why? And if it can be repaired without skipping this flag?
EDIT3: Well, nevermind. It seems that I can actually omit this flag.
Try removing "stackSize = 1;"
A patch to glibc is needed. Look here.
As noted in the patch, user applications using backtrace need to be compiled with "-fexceptions". If you want full symbol resolution of addresses you need "-rdynamic" too.
The compiler may be inlining those functions. Could try recompiling with the -O0 option.