G++ ignoring private access - c++

I have the following simple program:
#include <iostream>
class foo
{
int a;
} foo;
int main()
{
foo.a = 42;
std::cout << foo.a;
}
It outputs "42" but it shouldn't, as a is clearly private as class members are private by default. I have G++ 5.3.1 is this a bug?

Related

the memory is released when passing to unordered_map by rvalue

I bulit it with -std=c++17 and tried both g++ and clang++ such as clang++ -std=c++17 <file>. It showed the same results.
unordered_map
Pass an unordered_map to rvalue parameter in a function and assign it to another reference. And the memory is not allowed out of the function.
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>
using namespace std;
typedef unordered_map<string, string> kw_t;
struct Bar {
kw_t &foo;
string bar;
};
list<Bar> bars;
void test(kw_t &&foo) {
cout << &foo["a"] << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo["a"] << endl;
}
int main()
{
test({{"a", "b"}});
cout << &bars.front().foo["a"] << endl;
return 0;
}
And it has output:
0x1f3ded8
0x1f3ded8
[1] 9776 segmentation fault (core dumped) ./a.o
list
But for other classes, such as list or self defined struct, the code can work.
#include <iostream>
#include <list>
#include <string>
using namespace std;
typedef list<string> args_t;
struct Bar {
args_t &foo;
string bar;
};
list<Bar> bars;
void test(args_t &&foo) {
cout << &foo.front() << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo.front() << endl;
}
int main()
{
test({"a", "b"});
cout << &bars.front().foo.front() << endl;
return 0;
}
It printed:
0x15a7ec0
0x15a7ec0
0x15a7ec0
Why can the second one work but the first not?
Edit1:
clang version 7.1.0
g++ (GCC) 9.3.0
Why can the second one work but the first not?
In both cases, behaviour of the program is undefined. So, it "can" or "may" or "is allowed to" appear to work (for whatever you perceive as "woking"). Or to not "work". Or to have any other behaviour.
To clarify, the lifetime of the temporary object to which the reference bars.front().foo was bound has ended, and so the reference is invalid. Calling a member function through the invalid reference results in undefined behaviour.
Is it an erroneous behavior for compiler?
No. The compiler is behaving correctly. Your programs however are broken.

Usage of warn_unused attribute for classes in C++

I have the following code:
test.cpp
#include <iostream>
using namespace std;
class [[warn_unused]] test{
int val;
public:
test() {
val = 0;
}
int getv() { return this->val; }
~test() {
cout << "end\n";
}
};
int main() {
test t1;
int t2 = t1.getv();
return 0;
}
I get the following warnings from the compiler on running g++ test.cpp. My g++ version is 9.2.1.
test.cpp:4:23: warning: ‘warn_unused’ attribute directive ignored [-Wattributes]
4 | class [[warn_unused]] test{
|
If I change the attribute to [[gnu::warn_unused]], then there are no warnings whether I use the class or not.

Is the use of `struct` well-defined in c++ function signatures?

This question is similar to, but more specific than, this other question:
using struct keyword in variable declaration in C++.
Consider the following program:
#include <stdio.h>
struct Foo {
int x;
int y;
};
Foo getFoo() {
Foo foo;
return foo;
}
int main(){
getFoo();
}
The above program compiles with g++ but not gcc.
We can modify the program as follows to make it compile with both gcc and g++:
#include <stdio.h>
struct Foo {
int x;
int y;
};
struct Foo getFoo() {
struct Foo foo;
return foo;
}
int main(){
getFoo();
}
Is this use of the struct keyword guaranteed by the standard to be well-defined in C++?
Yes. That's known as an elaborated-type-specifier.

how to correctly initialize a std::vector with type of a struct which contains a std::vector of std::thread

Here is a mini-example of my code, how to correctly initialize member pool_ in the constructor.
#include <vector>
#include <thread>
#include <iostream>
namespace b {
class A;
typedef void (A::*Func) (void);
struct c {
Func fun;
int num;
std::vector<std::thread> threads;
};
class A {
public:
A() {
pool_ = {{&A::func1, 1, }, {&A::func2, 2, }}; // how to initialize?
}
private:
std::vector<c> pool_;
void func1(void) { std::cout << "func1\n"; };
void func2(void) { std::cout << "func2\n"; };
void CreateThread(c& pool) {
for (int i = 0; i < pool.num; ++i) {
pool.threads.push_back(std::thread(pool.fun, this));
}
}
};
} // namespace b
int main() {
b::A a;
return 0;
}
Platform: Ubuntu 14.04 with g++ 4.8.4
compile command:
g++ -Wall -std=c++11 test.cc -lpthread -o test
The major error message is:
error: use of deleted function ‘std::thread::thread(std::thread&)’
I know it is because copy construction and assignment of std::thread is not allowed. But I tried other ways and failed.
Two steps to solving this elegantly:
provide a constructor for c that does 'the right thing'
struct c {
c(Func fun, int num, std::vector<std::thread> threads = {})
: fun(fun)
, num(num)
, threads(std::move(threads))
{}
Func fun;
int num;
std::vector<std::thread> threads;
};
Then neatly emplace your objects into pool_
A()
{
pool_.emplace_back(&A::func1, 1);
pool_.emplace_back(&A::func2, 2);
}

Is this name lookup in dependent base class with VC++ 2010 non-standard?

The code below does not compile on Ideone or Codepad, yielding errors like:
'X' was not declared in this scope
but it does on VC++ 2010:
#include <iostream>
#include <typeinfo>
template<typename T>
struct Base
{
typedef T X;
};
template<typename T>
struct Derived
:
Base<T>
{
static void print()
{
std::cout << typeid(X).name() << "\n";
}
};
int main()
{
Derived<int>::print();
Derived<char>::print();
Derived<float>::print();
return 0;
}
where it prints int, char and float. Should I change my code to:
template<typename T>
struct Derived
{
typedef Base<T> B;
static void print()
{
std::cout << typeid(typename B::X).name() << "\n";
}
};
in order to be standard-conforming?
If you meant the equivalent of this (note you have dropped the inheritance in your example):
template<typename T>
struct Derived : Base<T> {
static void print() {
std::cout << typeid(typename Base<T>::X).name() << "\n";
}
};
then yes, that is standard compliant code. But note that the result of typeid(some type).name() is implementation dependent. On GCC your main produces i, c and f.
$ g++ -Wall test.cpp
test.cpp: In static member function 'static void Derived::print()':
test.cpp:15:37: error: 'X' was not declared in this scope
$ g++ --version
g++ (SUSE Linux) 4.6.2