vendredi 1 janvier 2016

gdb executing the same statement twice

While trying to understand the functionality of the unique_ptr, I wrote following program

 1#include <memory>
 2
 3int main(int argc, char *argv[])
 4{
 5    int i;
 6    
 7    std::unique_ptr<int> a(&i);
 8    std::unique_ptr<int> c(a.get());
 9    
10    return 0;
11}

When I run this program through gdb I noticed that after "return 0" instruction at line no 10, gdb again goes back to execute line no. 8 instruction.

$ gdb ./unptr 
GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9
(gdb) b main
Breakpoint 1 at 0x400686: file unptr.cpp, line 4.
(gdb) run
Starting program: /home/sbahir/work/funstuff/cplusplus/unptr 

Breakpoint 1, main (argc=1, argv=0x7fffffffdae8) at unptr.cpp:4
4       {
(gdb) n
7               std::unique_ptr<int> a(&i);
(gdb) n
8               std::unique_ptr<int> c(a.get());
(gdb) n
10              return 0;
(gdb) n
8               std::unique_ptr<int> c(a.get());
(gdb) p a
$1 = std::unique_ptr<int> containing 0x7fffffffd9cc
(gdb) p c
$2 = std::unique_ptr<int> containing 0x7fffffffd9cc
(gdb) 

I am not able to understand why this is happening. It would be great if someone could please explain or point to some reference to the material.

Thanks

Does the standard specify which functions are declared inline?

So the question is, does the latest standard specify when a function in the standard C++ library is declared inline or not?

Looking at the algorithm header file from the Clang, GCC and MSVC implementations, every single function, except for the ones which are constexpr, are declared inline.

I was gonna go on and ask about when to inline and what not, but I don't wanna have the usual argument about how the compiler knows better or micro optimizations, so I probably shouldn't even let this sentence stay in the question. Oh wait...

need to define all available constructor forms in c++

I have a class like this:

class A{
    private:
        init(const std::string s=""){/*do something*/}
    public:
        A(){init();}
        A(const A&){init();}
        A(const std::string s){init(s);}
        A(const A&, const std::string s){init(s);}
};

Does it cover all the forms that constructors may be called?

What I am trying to do is, any object creation must call the init() function at first.

std::unordered_set::erase complexity

I don't understand, why has erase method of std::unordered_set O(N) complexity in worst case (where N is number of elements)? Standard (n4296) says what all three versions of erase method have O(a.size()) complexity in worst case (a is container), and invalidated only iterators which point to erased elements, but not all iterators (i.e. rehashing doesn't take place). This is true even for a version which takes one iterator argument and have constant complexity in average case. I think it is because that erase version returns an iterator to the next element, and this requires finding the first non-empty bucket after erased element, and it gives O(a.bucket_count()) complexity, but not O(a.size())!. Number of elements is not in direct ratio to the number of buckets. For example:

#include <iostream>
#include <unordered_set>
using namespace std;

int main()
{
    std::unordered_set<int> aSet;
    aSet.insert ({125, 126});
    aSet.rehash (1000);
    cout << aSet.size() << endl;
    cout << aSet.bucket_count() << endl;
}

Output is

Size: 2
Bucket count: 1031

The size of a container is only 2 and bucket_count is 1031. When erase method will be called, it will seek next non-empty bucket, which can be placed about the end, i.e. complexity is O(a.bucket_count()), but not O(a.size()). What is reason for which Standard gives O(a.size()) complexity?

Object return by value is best way in c++?

//demo.h

#ifndef _DEMO_H_
#define _DEMO_H_

class Demo {

public:
    Demo();
    Demo(Demo const & d);
    Demo(Demo && d);
    Demo & operator=(Demo && d);
    Demo & operator=(const Demo & d);
    ~Demo();
};

#endif

//Demo.cpp

#include<iostream>
#include "Demo.h"

using namespace std;

Demo::Demo() {
    cout << this << " - Demo::Demo() "  << endl;
}

Demo::Demo(Demo const & d) {
    cout << this <<  " - Demo::Demo(Demo const & )" << endl;

}

Demo::Demo(Demo && d) {
    cout << this << " - Demo::Demo(Demo &&)" <<endl;
}


Demo & Demo::operator=(Demo && d) {
    cout << this << " - Demo::operator =(Demo && ) " << endl;
    return *this;

}

Demo & Demo::operator=(const Demo & d) {
    cout << this << " - Demo::operator=(const Demo & d) " <<endl;
    return *this;
}

Demo::~Demo() {
    cout << this << " - Demo::~Demo() " <<endl;
}

//return_demo.cpp

#include "Demo.h"
#include <utility>
#include <iostream>

using namespace std;

Demo fun(){ Demo s; return s; }
Demo  gun(){ return move(Demo{}); }
Demo && rrfun(){ Demo s; return move(s); }

int main(){
    cout << " ------ Demo fun(){ Demo s; return s; } " << endl;
    Demo x=fun();
    cout << " addres of return value is " << &x << endl;

    cout << "\n move -------------" <<endl ;
    Demo xm=move(fun());
    cout << " addres of return value is " << &xm << endl;

    cout << " \n------ Demo  gun(){ return move(Demo{}); } " << endl;
    Demo y=gun();
    cout << " addres of return value is " << &y << endl;

    cout << "\n move -------------" <<endl ;
    Demo ym=move(gun());
    cout << " addres of return value is " << &ym << endl;

    cout << " \n------ Demo && rrfun(){ Demo s; return move(s); } " << endl;
    Demo z=rrfun();
    cout << " addres of return value is " << &z << endl;

    cout << "\n move -------------" <<endl ;
    Demo zm=move(rrfun());
    cout << " addres of return value is " << &zm << endl;

cout << " ------------- main end -------------- " << endl;

return 0;
}

//out put

 ------ Demo fun(){ Demo s; return s; } 
0x7ffc6f560b78 - Demo::Demo() 
 addres of return value is 0x7ffc6f560b78

 move -------------
0x7ffc6f560b7a - Demo::Demo() 
0x7ffc6f560b79 - Demo::Demo(Demo &&)
0x7ffc6f560b7a - Demo::~Demo() 
 addres of return value is 0x7ffc6f560b79

------ Demo  gun(){ return move(Demo{}); } 
0x7ffc6f560b4f - Demo::Demo() 
0x7ffc6f560b7b - Demo::Demo(Demo &&)
0x7ffc6f560b4f - Demo::~Demo() 
 addres of return value is 0x7ffc6f560b7b

 move -------------
0x7ffc6f560b4f - Demo::Demo() 
0x7ffc6f560b7d - Demo::Demo(Demo &&)
0x7ffc6f560b4f - Demo::~Demo() 
0x7ffc6f560b7c - Demo::Demo(Demo &&)
0x7ffc6f560b7d - Demo::~Demo() 
 addres of return value is 0x7ffc6f560b7c

------ Demo && rrfun(){ Demo s; return move(s); } 
0x7ffc6f560b4f - Demo::Demo() 
0x7ffc6f560b4f - Demo::~Demo() 
0x7ffc6f560b7e - Demo::Demo(Demo &&)
 addres of return value is 0x7ffc6f560b7e

 move -------------
0x7ffc6f560b4f - Demo::Demo() 
0x7ffc6f560b4f - Demo::~Demo() 
0x7ffc6f560b7f - Demo::Demo(Demo &&)
 addres of return value is 0x7ffc6f560b7f
 ------------- main end -------------- 
0x7ffc6f560b7f - Demo::~Demo() 
0x7ffc6f560b7e - Demo::~Demo() 
0x7ffc6f560b7c - Demo::~Demo() 
0x7ffc6f560b7b - Demo::~Demo() 
0x7ffc6f560b79 - Demo::~Demo() 
0x7ffc6f560b78 - Demo::~Demo() 

we are reusing the same object which is created inb fun() and no constructor is called while returning object ( ellison rule )

Demo fun(){ Demo s; return s; } 

we are calling move constructor while returning object and a new object is created in below functions

Demo  gun(){ return move(Demo{}); }
Demo && rrfun(){ Demo s; return move(s); }

from the above demo program and output can we assume that object return by value is better then returning the by move // rvale reference ??

fill structure in a custom function of std::min_element() using boost::bind()

Trying to save one iteration over my vector.

I have a vector<T> I need to find a minimum element in the vector.

I am using std::min_element. Now there is a requirement to create a custom structure, which has elements of <T> plus few extra, computed on the fly.

So I am trying to use a function with boost::bind() like this:

MyStruct myStructObj;
typename std::vector< T >::iterator it = std::min_element(V.begin(), V.end(), boost::bind(BuildStructAndFindMin, myStructObj, _1, _2));

but how should I define BuildStructAndFindMin function? Till now, i never needed to create a custom function like this.

  1. _1 and _2 represent two ref objects to contents of V. But which one is least of them? I mean: the std::min_element()'s definition is going to iterate over a vector. For a fist call, it would simply send first two elements. For a second call, third element from vector and last_found_min element will be sent. Which, _1 or _2 is going to be this last_found_min? How to return an iterator? My vague sketch is like this:

    std::vector< T >::iterator BuildStructAndFindMin (MyStruct& myStructObj, const T &a, const T &b)
    {
        if(<a_min_condition>) // I am aware of this if statement. Just assume it to be a<b
        {
            // the point which is greater - create a struct object for that
            // and push_back in myStructObj
    
            return //what?;
        }
        else
        {
            // the point which is greater - create a struct object for that
            // and push_back in myStructObj
    
            return //what?
        }
    }
    
    

and after calling this function, I will have a min_element, but it will not be present in myStructObj. So I will insert it at the beginning.

The whole point in doing this drama is to save one iteration.

The easiest way out would have been: iterate over a vector and build a structure. And then call std::min_element(). But somehow, I am fighting for few nanoseconds and time is money in this case.

Warning: defaulted move assignment operator of X will move assign virtual base class Y multiple times

I'm catching a warning under Clang when testing a library under C++11. I've never come across the warning before and searching is not providing too much in the way of reading and research.

The warning is shown below, and it appears to be related to multiple inheritance and a common base class. But I'm not clear on the details triggering the warning or what I should do to address it.

My first question is, Is this a problem that needs to be addressed? Or is it a matter of efficiency alone?

My second question is (if needed), How do I address the warning? Or what are the options available to remediate it?


Here is some additional information:

  • Compiler: Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
  • g++ -DDEBUG -g2 -O2 -std=c++11 -fPIC -march=native -pipe -c test.cpp

Is also reviewed the following on Stack Overflow, but its not clear to me where they intersect:

The library, Crypto++, also make heavy use of Curiously Recurring Template Pattern for compile time polymorphism.


The the header file is available online, and here is the actual warning:

g++ -DDEBUG -g2 -O2 -std=c++11  -Wno-deprecated-declarations -fPIC -march=native -pipe -c rsa.cpp
In file included from rsa.cpp:4:
In file included from ./rsa.h:12:
./pubkey.h:635:26: warning: defaulted move assignment operator of 'InvertibleRSAFunction' will move assign virtual base class 'CryptoMaterial' multiple times [-Wmultiple-move-vbase]
class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS>
                         ^
./rsa.h:57:44: note: 'CryptoMaterial' is a virtual base class of base class 'CryptoPP::RSAFunction' declared here
class CRYPTOPP_DLL InvertibleRSAFunction : public RSAFunction, public TrapdoorFunctionInverse, public PKCS8PrivateKey
                                           ^~~~~~~~~~~~~~~~~~
./rsa.h:57:96: note: 'CryptoMaterial' is a virtual base class of base class 'CryptoPP::PKCS8PrivateKey' declared here
class CRYPTOPP_DLL InvertibleRSAFunction : public RSAFunction, public TrapdoorFunctionInverse, public PKCS8PrivateKey
                                                                                               ^
1 warning generated.

My apologies for not reducing it. I'm not sure how to reduce it and capture the essence of the warning/complaint.