0

In my class, I have two vector objects:

std::vector<std::string> vecteur_noms_A_;
std::vector<std::string> vecteur_noms_B_;

I also have the following function:

std::vector<std::string> & get_vecteur_noms_A_() {      
 return vecteur_noms_A_;    
}

but I do not have the same for the B one!

When I instantiate my class, and do the following instructions in my class constructor; I can see (via debugging or when It throws an error) that:

vecteur_noms_A_.push_back("some value"); // is ok

vecteur_noms_B_.push_back("some other value"); // is not ok <- throws an error.

Debugging let me see that an object (or instance ?)(empty vector) is existing for vecteur_noms_A_ but not for vecteur_noms_B_.

It is not clear why I observe that comportment I did not expect, I would be happy if I get an explanation.

Does the fact that I define a function forces the compiler to instanciate the object?

Here is an example :

#include <iostream>
#include <vector>

using namespace std;
class GP 
{
public:
    //Constructeur
    GP(std::vector<std::string> list_names_A, std::vector<std::string> list_names_B
);

    //Fonctions
    void construction_vecteur_A_B_(std::vector<std::string> list_names_A, std::vector<std::string> list_names_B);


    std::vector<std::string>& get_vecteur_noms_A() {
        return vecteur_noms_A_;
    }

    std::vector<std::string> vecteur_noms_A_;
    std::vector<std::string> vecteur_noms_B_;
};



GP::GP(std::vector<std::string> list_names_a, std::vector<std::string> list_names_b)  {

construction_vecteur_A_B_(list_names_a, list_names_b);

            }


void GP::construction_vecteur_A_B_(std::vector<std::string> list_names_a,     std::vector<std::string> list_names_b)
{
    for (int i = 0; i < list_names_a.size(); i++) {
        vecteur_noms_A_.push_back(list_names_a[i]);
    }
    for (int i = 0; i < list_names_b.size(); i++) {
        vecteur_noms_B_.push_back(list_names_b[i]);
    }
}    


int main()
{

    std::vector<std::string> list_names_A = std::vector<std::string>();
    std::vector<std::string> list_names_B = std::vector<std::string>();
    list_names_A.push_back("A");
    list_names_B.push_back("B");

GP(list_names_A, list_names_B);

    return 0;
}

Since the program written here weems to throw no error, I would like to uderstand why :

vecteur_noms_A_

and

vecteur_noms_B_

are existing at execution so that I can do the pushback. Why isn't it necessary to apply this to them in the constructor:

vecteur_noms_A_  = std::vector<std::string>();
vecteur_noms_B_  = std::vector<std::string>();

Thanks for your help.

  • 2
    Please provide [mcve]. – Algirdas Preidžius Sep 03 '18 at 13:12
  • 6
    I think we'll need the shortest complete program you can conjure up to be able to make sense of this. – Bathsheba Sep 03 '18 at 13:12
  • 2
    Ok, I'll provide one. Thanks for asking for this – StudentInFinance Sep 03 '18 at 13:14
  • If you never use a variable, the compiler may not create it. – stark Sep 03 '18 at 13:16
  • @stark what? it is about member variables. A compiler that removes members because it thinks they are not used I would consider as broken – 463035818_is_not_an_ai Sep 03 '18 at 13:18
  • @StudentInFinance If you had read through [ask], and [help], **before** asking, you would have known, that you needed to provide [mcve], without anyone pointing that out for you. – Algirdas Preidžius Sep 03 '18 at 13:19
  • @stark - The compiler does not remove class data attributes when unused. On ubuntu, even an empty std::vector takes 24 bytes. This contributes to the size of the class instance. Simply cout the sizeof() the class or instance to confirm. – 2785528 Sep 03 '18 at 13:29
  • according to https://stackoverflow.com/questions/31885337/what-compiler-is-in-visual-studio-2015 , I m using Visual C++ 14.1 – StudentInFinance Sep 03 '18 at 13:36
  • Please be more specific than "throws an error" and "returns an error". Like *what* error, exactly? (By the way, throwing and returning mean very specific, and very different, things.) – molbdnilo Sep 03 '18 at 13:38
  • 1
    You should read more about the "Complete" and "Verifiable" parts of the [mcve]. – molbdnilo Sep 03 '18 at 13:41
  • what you have there is just a class definition, there is no chance this crashes at runtime, actually as is this [does not compile](https://wandbox.org/permlink/pWI0l2sgrbuIplkV) – 463035818_is_not_an_ai Sep 03 '18 at 13:42
  • Possible duplicate of [Can unused data members be optimized out in C++](https://stackoverflow.com/questions/23176564/can-unused-data-members-be-optimized-out-in-c) – PraAnj Sep 03 '18 at 14:02
  • Here the difference is that: vecteur_noms_A_ and vecteur_noms_B_ are data members that are used. I just figured out that the prpovided example seems to work fine (no error thrown), but 2 days ago I observed that list_names_B did not exist at runtime . I had to I add the function std::vector& get_vecteur_noms_B() to solve this. Now, it still executes normaly whereas the function get_vecteur_noms_B() is removed. I have no explecation for what I observed, and why it does not reproduce now. – StudentInFinance Sep 03 '18 at 14:38
  • 1
    Please provide a complete program, with main(), #includes and everything else. It's hard to figure out what is going on when you only give snippets. – PlinyTheElder Sep 03 '18 at 14:57
  • 1
    It is unclear what you expect to happen in your program,, and how it contradicts your observations. – n. m. could be an AI Sep 03 '18 at 16:03
  • The easiest way to explain your expectations is to say "I expect the program to print A, but it prints B" (or prints nothing, or crashes). Your program doesn't appear to print anything so it's hard to discuss its observable behaviour. – n. m. could be an AI Sep 03 '18 at 16:10
  • I expect the programm to throw no error. I observe that the programm throw no error. BUT 3 days ago, I had a very similar code and the vector was not initialized when construction_vecteur_A_B_ was called and it threw an error. I couldn t figure out why. I observed that it had no get_vecteur_noms_[X]() function. I simply add it and it did not crash anymore. Today, I said to myself that there were no reason why adding the function would solve the error. That's why I asked on this site for explanations. I tried to reproduce the error to share it here, but I just can't reproduce it. It's confsing – StudentInFinance Sep 03 '18 at 16:59

1 Answers1

1

With regards to your last question. It is not necessary to assign a value, such as std::vector<std::string>(), to the member vectors, vecteur_noms_A_, vecteur_noms_B_ as they are default constructed, when your class GP is used, before the body of the constructor is executed.

Notice therefore that if you were to do the following in the body of the constructor of GP:

vecteur_noms_A_  = std::vector<std::string>();
vecteur_noms_B_  = std::vector<std::string>();

It would be equivalent to the following operation:

vecteur_noms_A_.operator=(std::vector<std::string>());
vecteur_noms_B_.operator=(std::vector<std::string>());

That is you are assigning an empty vector (using the copy assignment operator) to your already default constructed empty vector, which is redundant.

Alexander
  • 410
  • 5
  • 14
  • Thanks Alexander for these elements. I understand that members of a class will be default constructed unless a specific construction is set after the ":" in the constructor definition. Do you know a way, that could cause a non-defualt construction of vecteur_noms_B_ ? It seems it is what happened to me 3 days ago, but I can't reproduce what caused it (cf. 1st part of this StackOverflow question). Thanks – StudentInFinance Sep 03 '18 at 16:02
  • Unfortunately, as has been mentioned by others in the comments, without a way of reproducing the error you experienced, or more clearly understand the steps required to throw the error, it's not possible to say much. When the vector is created you need not use the default constructor, the vector class has other constructors (https://en.cppreference.com/w/cpp/container/vector/vector) but it is not clear what that has to do with the problem you reported. – Alexander Sep 03 '18 at 16:13