Does a member have to be initialized to take its address?Is it safe to use the “this” pointer in an initialization list?C++ Get class member address in constructor initialization listWhat does the explicit keyword mean?How to initialize private static members in C++?How to initialize all members of an array to the same value?Efficiency of Java “Double Brace Initialization”?Initialization of an ArrayList in one lineStatic constant string (class member)How do C++ class members get initialized if I don't do it explicitly?JavaScript check if variable exists (is defined/initialized)C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?How to directly initialize a HashMap (in a literal way)?

Does it matter what way the tires go if no directional arrow?

What is the effect of the Feeblemind spell on Ability Score Improvements?

I recently started my machine learning PhD and I have absolutely no idea what I'm doing

Why didn't the Avengers use this object earlier?

Why when I add jam to my tea it stops producing thin "membrane" on top?

Does the wearer know what items are in which patch in the Robe of Useful items?

enumitem: Understanding the usage of asterisk and exclamation mark in setting the different lengths

What dog breeds survive the apocalypse for generations?

How to continually let my readers know what time it is in my story, in an organic way?

How to not get blinded by an attack at dawn

Can a tourist shoot a gun in the USA?

With today's technology, could iron be smelted at La Rinconada?

Is the seat-belt sign activation when a pilot goes to the lavatory standard procedure?

What is this weird d12 for?

Single word that parallels "Recent" when discussing the near future

Meaning of "legitimate" in Carl Jung's quote "Neurosis is always a substitute for legitimate suffering."

c++ conditional uni-directional iterator

Why are goodwill impairments on the statement of cash-flows of GE?

Holding rent money for my friend which amounts to over $10k?

Do people who work at research institutes consider themselves "academics"?

How to redirect stdout to a file, and stdout+stderr to another one?

How much outgoing traffic would a HTTP load balance use?

Why can't I share a one use code with anyone else?

Would life always name the light from their sun "white"



Does a member have to be initialized to take its address?


Is it safe to use the “this” pointer in an initialization list?C++ Get class member address in constructor initialization listWhat does the explicit keyword mean?How to initialize private static members in C++?How to initialize all members of an array to the same value?Efficiency of Java “Double Brace Initialization”?Initialization of an ArrayList in one lineStatic constant string (class member)How do C++ class members get initialized if I don't do it explicitly?JavaScript check if variable exists (is defined/initialized)C++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?How to directly initialize a HashMap (in a literal way)?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








20















Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?



#include <string>

class Klass
public:
Klass()
: ptr_str&str
, str

private:
std::string *ptr_str;
std::string str;
;


this question is similar to mine, but the order is correct there, and the answer says




I'd advise against coding like this in case someone changes the order of the members in your class.




Which seems to mean reversing the order would be illegal but I couldn't be sure.










share|improve this question
























  • Just curious why do you need it?

    – vahancho
    May 10 at 13:45







  • 1





    @vahancho I am adding a private vector to the end of a class (so it is physically separate from the interface) but this vector takes pointers to some public members. I would like to know if I have to move it up or if this is fine.

    – Ayxan
    May 10 at 13:51







  • 1





    just make sure you do not try to access the member before its actually there

    – formerlyknownas_463035818
    May 10 at 13:56






  • 2





    @Ayxan Language-lawyer questions might bring into this site interesting discussions. I would therefore suggest to wait a little longer with such a quick acceptance of the first answer. Though it may be correct, other opinions might be valuable as well.

    – Daniel Langr
    May 10 at 14:01












  • @DanielLangr nice suggestion.

    – Ayxan
    May 10 at 14:03

















20















Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?



#include <string>

class Klass
public:
Klass()
: ptr_str&str
, str

private:
std::string *ptr_str;
std::string str;
;


this question is similar to mine, but the order is correct there, and the answer says




I'd advise against coding like this in case someone changes the order of the members in your class.




Which seems to mean reversing the order would be illegal but I couldn't be sure.










share|improve this question
























  • Just curious why do you need it?

    – vahancho
    May 10 at 13:45







  • 1





    @vahancho I am adding a private vector to the end of a class (so it is physically separate from the interface) but this vector takes pointers to some public members. I would like to know if I have to move it up or if this is fine.

    – Ayxan
    May 10 at 13:51







  • 1





    just make sure you do not try to access the member before its actually there

    – formerlyknownas_463035818
    May 10 at 13:56






  • 2





    @Ayxan Language-lawyer questions might bring into this site interesting discussions. I would therefore suggest to wait a little longer with such a quick acceptance of the first answer. Though it may be correct, other opinions might be valuable as well.

    – Daniel Langr
    May 10 at 14:01












  • @DanielLangr nice suggestion.

    – Ayxan
    May 10 at 14:03













20












20








20


1






Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?



#include <string>

class Klass
public:
Klass()
: ptr_str&str
, str

private:
std::string *ptr_str;
std::string str;
;


this question is similar to mine, but the order is correct there, and the answer says




I'd advise against coding like this in case someone changes the order of the members in your class.




Which seems to mean reversing the order would be illegal but I couldn't be sure.










share|improve this question
















Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?



#include <string>

class Klass
public:
Klass()
: ptr_str&str
, str

private:
std::string *ptr_str;
std::string str;
;


this question is similar to mine, but the order is correct there, and the answer says




I'd advise against coding like this in case someone changes the order of the members in your class.




Which seems to mean reversing the order would be illegal but I couldn't be sure.







c++ pointers initialization language-lawyer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 10 at 14:16







Ayxan

















asked May 10 at 13:43









AyxanAyxan

2,722724




2,722724












  • Just curious why do you need it?

    – vahancho
    May 10 at 13:45







  • 1





    @vahancho I am adding a private vector to the end of a class (so it is physically separate from the interface) but this vector takes pointers to some public members. I would like to know if I have to move it up or if this is fine.

    – Ayxan
    May 10 at 13:51







  • 1





    just make sure you do not try to access the member before its actually there

    – formerlyknownas_463035818
    May 10 at 13:56






  • 2





    @Ayxan Language-lawyer questions might bring into this site interesting discussions. I would therefore suggest to wait a little longer with such a quick acceptance of the first answer. Though it may be correct, other opinions might be valuable as well.

    – Daniel Langr
    May 10 at 14:01












  • @DanielLangr nice suggestion.

    – Ayxan
    May 10 at 14:03

















  • Just curious why do you need it?

    – vahancho
    May 10 at 13:45







  • 1





    @vahancho I am adding a private vector to the end of a class (so it is physically separate from the interface) but this vector takes pointers to some public members. I would like to know if I have to move it up or if this is fine.

    – Ayxan
    May 10 at 13:51







  • 1





    just make sure you do not try to access the member before its actually there

    – formerlyknownas_463035818
    May 10 at 13:56






  • 2





    @Ayxan Language-lawyer questions might bring into this site interesting discussions. I would therefore suggest to wait a little longer with such a quick acceptance of the first answer. Though it may be correct, other opinions might be valuable as well.

    – Daniel Langr
    May 10 at 14:01












  • @DanielLangr nice suggestion.

    – Ayxan
    May 10 at 14:03
















Just curious why do you need it?

– vahancho
May 10 at 13:45






Just curious why do you need it?

– vahancho
May 10 at 13:45





1




1





@vahancho I am adding a private vector to the end of a class (so it is physically separate from the interface) but this vector takes pointers to some public members. I would like to know if I have to move it up or if this is fine.

– Ayxan
May 10 at 13:51






@vahancho I am adding a private vector to the end of a class (so it is physically separate from the interface) but this vector takes pointers to some public members. I would like to know if I have to move it up or if this is fine.

– Ayxan
May 10 at 13:51





1




1





just make sure you do not try to access the member before its actually there

– formerlyknownas_463035818
May 10 at 13:56





just make sure you do not try to access the member before its actually there

– formerlyknownas_463035818
May 10 at 13:56




2




2





@Ayxan Language-lawyer questions might bring into this site interesting discussions. I would therefore suggest to wait a little longer with such a quick acceptance of the first answer. Though it may be correct, other opinions might be valuable as well.

– Daniel Langr
May 10 at 14:01






@Ayxan Language-lawyer questions might bring into this site interesting discussions. I would therefore suggest to wait a little longer with such a quick acceptance of the first answer. Though it may be correct, other opinions might be valuable as well.

– Daniel Langr
May 10 at 14:01














@DanielLangr nice suggestion.

– Ayxan
May 10 at 14:03





@DanielLangr nice suggestion.

– Ayxan
May 10 at 14:03












2 Answers
2






active

oldest

votes


















24















Does a member have to be initialized to take its address?




No.




Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?




Yes. Yes.



There is no restriction that operand of unary & need to be initialised. There is an example in the standard in specification of unary & operator:




int a;
int* p1 = &a;



Here, the value of a is uninitialized and it is OK to point to it.



What that example doesn't demonstrate is pointing to an object before its lifetime has begun, which is what happens in your example. Using a pointer to an object before and after its lifetime is explicitly allowed if the storage is occupied. Standard draft says:




[basic.life] Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways ...




The rule goes on to list how the usage is restricted. You can get by with common sense. In short, you can treat it as you could treat a void*, except violating these restrictions is UB rather than ill-formed. Similar rule exists for references.



There are also restrictions on computing the address of non-static members specifically. Standard draft says:




[class.cdtor] ... To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member value) results in undefined behavior.




In the constructor of Klass, the construction of Klass has started and destruction hasn't completed, so the above rule is satisfied.




P.S. Your class is copyable, but the copy will have a pointer to the member of another instance. Consider whether that makes sense for your class. If not, you will need to implement custom copy and move constructors and assignment operators. A self-reference like this is a rare case where you may need custom definitions for those, but not a custom destructor, so it is an exception to the rule of five (or three).



P.P.S If your intention is to point to one of the members, and no object other than a member, then you might want to use a pointer to member instead of pointer to object.






share|improve this answer




















  • 7





    It would be nice to quote relevant parts of the Standard. These might be relevant: eel.is/c++draft/basic.life#6.sentence-1 and eel.is/c++draft/class.cdtor#3.sentence-2.

    – Daniel Langr
    May 10 at 13:58







  • 1





    @DanielLangr Thanks for looking those up.

    – eerorika
    May 10 at 14:05






  • 1





    There's a subtle difference between your example and the OP's example. In your example, the lifetime of the variable a has begun, but it was not initialized. In the OP's example, the address of a member is taken before its lifetime. Given that your quotations of the standard already adequately address the OP's question, I think the example should be deleted.

    – Brian
    May 10 at 14:57






  • 1





    @Brian OP's specifically asks about initialization. The quoted rule doesn't explicitly address initialization (no rule addresses it; there simply isn't a rule related to initialization to my knowledge). Sure, lack of lifetime implies lack of initialization, but I prefer to be explicit. In my opinion, the example demonstrating lack of initialization is useful even if it is technically made redundant by the lifetime rule.

    – eerorika
    May 10 at 15:10



















-1














Funny question.



It is legitimate and will "work", though barely. There is a little "but" related to types which makes the whole thing a bit awkward with a bad taste (but not illegitimate), and which might make it illegal some border cases involving inheritance.



You can, of course, take the address of any object whether it's initialized or not, as long as it exists in the scope and has a name which you can prepend operator& to. Dereferencing the pointer is a different thing, but that wasn't the question.



Now, the subtle problem is that the standard defines the result of operator& for non-static struct members as "“pointer to member of class C of type T” and is a prvalue designating C::m".



Which basically means that ptr_str&str will take the address of str, but the type is not pointer-to, but pointer-to-member-of. It is then implicitly and silently cast to pointer-to.



In other words, although you do not need to explicitly write &this->str, that's nevertheless what its type is -- it's what it is and what it means [1].



Is this valid, and is it safe to use it within the initializer list? Well yes, just... barely. It's safe to use it as long as it's not being used to access uninitialized members or virtual functions, directly or indirectly. Which, as it happens, is the case here (it might not be the case in a different, arguably contrieved case).





[1] Funnily, paragraph 4 starts with a clause that says that no member pointer is formed when you put stuff in parenthese. That's remarkable because most people would probably do that just to be 100% sure they got operator precedence right. But if I read correctly, then &this->foo and &(this->foo) are not in any way the same!




share|improve this answer























  • Wow, I had to read it twice. What I understood is that the code I've got there is strictly speaking illegal (since it uses this to access an uninitialized member), and it is so subtle that I'd better avoid it altogether. Is that correct?

    – Ayxan
    May 10 at 17:21







  • 1





    No, no, no. It is strictly legal. But it gets very "close" to being illegal. Close, but not over the line. You are not using this to access an uninitialized member, you are using it to take the uninitialized member's address. Which is just as much as you are allowed to do legitimately (for complete members of the same class or superclasses, but not subclasses or members of incomplete type). While not wrong, I would personally nevertheless avoid it because it makes me feel funny (legitimate as it may be).

    – Damon
    May 10 at 17:32







  • 2





    No, & with an unqualified name never creates a pointer-to-member. If you wanted a pointer-to-member, you would have to write &Klass::str. Similarly, &this->foo and &(this->foo) are the same, both create ordinary pointers because these are member-access expressions, not qualified names.

    – Ben Voigt
    May 10 at 17:50







  • 2





    The Standard rule you link to starts out with "If the operand is a qualified-id" Which is why it does not apply here.

    – Ben Voigt
    May 10 at 17:52






  • 1





    Moreover, there are no implicit conversions from a pointer-to-member type to a pointer type (what object would it bind to?).

    – Sneftel
    May 10 at 17:54











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56078944%2fdoes-a-member-have-to-be-initialized-to-take-its-address%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









24















Does a member have to be initialized to take its address?




No.




Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?




Yes. Yes.



There is no restriction that operand of unary & need to be initialised. There is an example in the standard in specification of unary & operator:




int a;
int* p1 = &a;



Here, the value of a is uninitialized and it is OK to point to it.



What that example doesn't demonstrate is pointing to an object before its lifetime has begun, which is what happens in your example. Using a pointer to an object before and after its lifetime is explicitly allowed if the storage is occupied. Standard draft says:




[basic.life] Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways ...




The rule goes on to list how the usage is restricted. You can get by with common sense. In short, you can treat it as you could treat a void*, except violating these restrictions is UB rather than ill-formed. Similar rule exists for references.



There are also restrictions on computing the address of non-static members specifically. Standard draft says:




[class.cdtor] ... To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member value) results in undefined behavior.




In the constructor of Klass, the construction of Klass has started and destruction hasn't completed, so the above rule is satisfied.




P.S. Your class is copyable, but the copy will have a pointer to the member of another instance. Consider whether that makes sense for your class. If not, you will need to implement custom copy and move constructors and assignment operators. A self-reference like this is a rare case where you may need custom definitions for those, but not a custom destructor, so it is an exception to the rule of five (or three).



P.P.S If your intention is to point to one of the members, and no object other than a member, then you might want to use a pointer to member instead of pointer to object.






share|improve this answer




















  • 7





    It would be nice to quote relevant parts of the Standard. These might be relevant: eel.is/c++draft/basic.life#6.sentence-1 and eel.is/c++draft/class.cdtor#3.sentence-2.

    – Daniel Langr
    May 10 at 13:58







  • 1





    @DanielLangr Thanks for looking those up.

    – eerorika
    May 10 at 14:05






  • 1





    There's a subtle difference between your example and the OP's example. In your example, the lifetime of the variable a has begun, but it was not initialized. In the OP's example, the address of a member is taken before its lifetime. Given that your quotations of the standard already adequately address the OP's question, I think the example should be deleted.

    – Brian
    May 10 at 14:57






  • 1





    @Brian OP's specifically asks about initialization. The quoted rule doesn't explicitly address initialization (no rule addresses it; there simply isn't a rule related to initialization to my knowledge). Sure, lack of lifetime implies lack of initialization, but I prefer to be explicit. In my opinion, the example demonstrating lack of initialization is useful even if it is technically made redundant by the lifetime rule.

    – eerorika
    May 10 at 15:10
















24















Does a member have to be initialized to take its address?




No.




Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?




Yes. Yes.



There is no restriction that operand of unary & need to be initialised. There is an example in the standard in specification of unary & operator:




int a;
int* p1 = &a;



Here, the value of a is uninitialized and it is OK to point to it.



What that example doesn't demonstrate is pointing to an object before its lifetime has begun, which is what happens in your example. Using a pointer to an object before and after its lifetime is explicitly allowed if the storage is occupied. Standard draft says:




[basic.life] Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways ...




The rule goes on to list how the usage is restricted. You can get by with common sense. In short, you can treat it as you could treat a void*, except violating these restrictions is UB rather than ill-formed. Similar rule exists for references.



There are also restrictions on computing the address of non-static members specifically. Standard draft says:




[class.cdtor] ... To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member value) results in undefined behavior.




In the constructor of Klass, the construction of Klass has started and destruction hasn't completed, so the above rule is satisfied.




P.S. Your class is copyable, but the copy will have a pointer to the member of another instance. Consider whether that makes sense for your class. If not, you will need to implement custom copy and move constructors and assignment operators. A self-reference like this is a rare case where you may need custom definitions for those, but not a custom destructor, so it is an exception to the rule of five (or three).



P.P.S If your intention is to point to one of the members, and no object other than a member, then you might want to use a pointer to member instead of pointer to object.






share|improve this answer




















  • 7





    It would be nice to quote relevant parts of the Standard. These might be relevant: eel.is/c++draft/basic.life#6.sentence-1 and eel.is/c++draft/class.cdtor#3.sentence-2.

    – Daniel Langr
    May 10 at 13:58







  • 1





    @DanielLangr Thanks for looking those up.

    – eerorika
    May 10 at 14:05






  • 1





    There's a subtle difference between your example and the OP's example. In your example, the lifetime of the variable a has begun, but it was not initialized. In the OP's example, the address of a member is taken before its lifetime. Given that your quotations of the standard already adequately address the OP's question, I think the example should be deleted.

    – Brian
    May 10 at 14:57






  • 1





    @Brian OP's specifically asks about initialization. The quoted rule doesn't explicitly address initialization (no rule addresses it; there simply isn't a rule related to initialization to my knowledge). Sure, lack of lifetime implies lack of initialization, but I prefer to be explicit. In my opinion, the example demonstrating lack of initialization is useful even if it is technically made redundant by the lifetime rule.

    – eerorika
    May 10 at 15:10














24












24








24








Does a member have to be initialized to take its address?




No.




Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?




Yes. Yes.



There is no restriction that operand of unary & need to be initialised. There is an example in the standard in specification of unary & operator:




int a;
int* p1 = &a;



Here, the value of a is uninitialized and it is OK to point to it.



What that example doesn't demonstrate is pointing to an object before its lifetime has begun, which is what happens in your example. Using a pointer to an object before and after its lifetime is explicitly allowed if the storage is occupied. Standard draft says:




[basic.life] Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways ...




The rule goes on to list how the usage is restricted. You can get by with common sense. In short, you can treat it as you could treat a void*, except violating these restrictions is UB rather than ill-formed. Similar rule exists for references.



There are also restrictions on computing the address of non-static members specifically. Standard draft says:




[class.cdtor] ... To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member value) results in undefined behavior.




In the constructor of Klass, the construction of Klass has started and destruction hasn't completed, so the above rule is satisfied.




P.S. Your class is copyable, but the copy will have a pointer to the member of another instance. Consider whether that makes sense for your class. If not, you will need to implement custom copy and move constructors and assignment operators. A self-reference like this is a rare case where you may need custom definitions for those, but not a custom destructor, so it is an exception to the rule of five (or three).



P.P.S If your intention is to point to one of the members, and no object other than a member, then you might want to use a pointer to member instead of pointer to object.






share|improve this answer
















Does a member have to be initialized to take its address?




No.




Can I initialize a pointer to a data member before initializing the member? In other words, is this valid C++?




Yes. Yes.



There is no restriction that operand of unary & need to be initialised. There is an example in the standard in specification of unary & operator:




int a;
int* p1 = &a;



Here, the value of a is uninitialized and it is OK to point to it.



What that example doesn't demonstrate is pointing to an object before its lifetime has begun, which is what happens in your example. Using a pointer to an object before and after its lifetime is explicitly allowed if the storage is occupied. Standard draft says:




[basic.life] Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways ...




The rule goes on to list how the usage is restricted. You can get by with common sense. In short, you can treat it as you could treat a void*, except violating these restrictions is UB rather than ill-formed. Similar rule exists for references.



There are also restrictions on computing the address of non-static members specifically. Standard draft says:




[class.cdtor] ... To form a pointer to (or access the value of) a direct non-static member of an object obj, the construction of obj shall have started and its destruction shall not have completed, otherwise the computation of the pointer value (or accessing the member value) results in undefined behavior.




In the constructor of Klass, the construction of Klass has started and destruction hasn't completed, so the above rule is satisfied.




P.S. Your class is copyable, but the copy will have a pointer to the member of another instance. Consider whether that makes sense for your class. If not, you will need to implement custom copy and move constructors and assignment operators. A self-reference like this is a rare case where you may need custom definitions for those, but not a custom destructor, so it is an exception to the rule of five (or three).



P.P.S If your intention is to point to one of the members, and no object other than a member, then you might want to use a pointer to member instead of pointer to object.







share|improve this answer














share|improve this answer



share|improve this answer








edited May 10 at 15:15

























answered May 10 at 13:55









eerorikaeerorika

92k667138




92k667138







  • 7





    It would be nice to quote relevant parts of the Standard. These might be relevant: eel.is/c++draft/basic.life#6.sentence-1 and eel.is/c++draft/class.cdtor#3.sentence-2.

    – Daniel Langr
    May 10 at 13:58







  • 1





    @DanielLangr Thanks for looking those up.

    – eerorika
    May 10 at 14:05






  • 1





    There's a subtle difference between your example and the OP's example. In your example, the lifetime of the variable a has begun, but it was not initialized. In the OP's example, the address of a member is taken before its lifetime. Given that your quotations of the standard already adequately address the OP's question, I think the example should be deleted.

    – Brian
    May 10 at 14:57






  • 1





    @Brian OP's specifically asks about initialization. The quoted rule doesn't explicitly address initialization (no rule addresses it; there simply isn't a rule related to initialization to my knowledge). Sure, lack of lifetime implies lack of initialization, but I prefer to be explicit. In my opinion, the example demonstrating lack of initialization is useful even if it is technically made redundant by the lifetime rule.

    – eerorika
    May 10 at 15:10













  • 7





    It would be nice to quote relevant parts of the Standard. These might be relevant: eel.is/c++draft/basic.life#6.sentence-1 and eel.is/c++draft/class.cdtor#3.sentence-2.

    – Daniel Langr
    May 10 at 13:58







  • 1





    @DanielLangr Thanks for looking those up.

    – eerorika
    May 10 at 14:05






  • 1





    There's a subtle difference between your example and the OP's example. In your example, the lifetime of the variable a has begun, but it was not initialized. In the OP's example, the address of a member is taken before its lifetime. Given that your quotations of the standard already adequately address the OP's question, I think the example should be deleted.

    – Brian
    May 10 at 14:57






  • 1





    @Brian OP's specifically asks about initialization. The quoted rule doesn't explicitly address initialization (no rule addresses it; there simply isn't a rule related to initialization to my knowledge). Sure, lack of lifetime implies lack of initialization, but I prefer to be explicit. In my opinion, the example demonstrating lack of initialization is useful even if it is technically made redundant by the lifetime rule.

    – eerorika
    May 10 at 15:10








7




7





It would be nice to quote relevant parts of the Standard. These might be relevant: eel.is/c++draft/basic.life#6.sentence-1 and eel.is/c++draft/class.cdtor#3.sentence-2.

– Daniel Langr
May 10 at 13:58






It would be nice to quote relevant parts of the Standard. These might be relevant: eel.is/c++draft/basic.life#6.sentence-1 and eel.is/c++draft/class.cdtor#3.sentence-2.

– Daniel Langr
May 10 at 13:58





1




1





@DanielLangr Thanks for looking those up.

– eerorika
May 10 at 14:05





@DanielLangr Thanks for looking those up.

– eerorika
May 10 at 14:05




1




1





There's a subtle difference between your example and the OP's example. In your example, the lifetime of the variable a has begun, but it was not initialized. In the OP's example, the address of a member is taken before its lifetime. Given that your quotations of the standard already adequately address the OP's question, I think the example should be deleted.

– Brian
May 10 at 14:57





There's a subtle difference between your example and the OP's example. In your example, the lifetime of the variable a has begun, but it was not initialized. In the OP's example, the address of a member is taken before its lifetime. Given that your quotations of the standard already adequately address the OP's question, I think the example should be deleted.

– Brian
May 10 at 14:57




1




1





@Brian OP's specifically asks about initialization. The quoted rule doesn't explicitly address initialization (no rule addresses it; there simply isn't a rule related to initialization to my knowledge). Sure, lack of lifetime implies lack of initialization, but I prefer to be explicit. In my opinion, the example demonstrating lack of initialization is useful even if it is technically made redundant by the lifetime rule.

– eerorika
May 10 at 15:10






@Brian OP's specifically asks about initialization. The quoted rule doesn't explicitly address initialization (no rule addresses it; there simply isn't a rule related to initialization to my knowledge). Sure, lack of lifetime implies lack of initialization, but I prefer to be explicit. In my opinion, the example demonstrating lack of initialization is useful even if it is technically made redundant by the lifetime rule.

– eerorika
May 10 at 15:10














-1














Funny question.



It is legitimate and will "work", though barely. There is a little "but" related to types which makes the whole thing a bit awkward with a bad taste (but not illegitimate), and which might make it illegal some border cases involving inheritance.



You can, of course, take the address of any object whether it's initialized or not, as long as it exists in the scope and has a name which you can prepend operator& to. Dereferencing the pointer is a different thing, but that wasn't the question.



Now, the subtle problem is that the standard defines the result of operator& for non-static struct members as "“pointer to member of class C of type T” and is a prvalue designating C::m".



Which basically means that ptr_str&str will take the address of str, but the type is not pointer-to, but pointer-to-member-of. It is then implicitly and silently cast to pointer-to.



In other words, although you do not need to explicitly write &this->str, that's nevertheless what its type is -- it's what it is and what it means [1].



Is this valid, and is it safe to use it within the initializer list? Well yes, just... barely. It's safe to use it as long as it's not being used to access uninitialized members or virtual functions, directly or indirectly. Which, as it happens, is the case here (it might not be the case in a different, arguably contrieved case).





[1] Funnily, paragraph 4 starts with a clause that says that no member pointer is formed when you put stuff in parenthese. That's remarkable because most people would probably do that just to be 100% sure they got operator precedence right. But if I read correctly, then &this->foo and &(this->foo) are not in any way the same!




share|improve this answer























  • Wow, I had to read it twice. What I understood is that the code I've got there is strictly speaking illegal (since it uses this to access an uninitialized member), and it is so subtle that I'd better avoid it altogether. Is that correct?

    – Ayxan
    May 10 at 17:21







  • 1





    No, no, no. It is strictly legal. But it gets very "close" to being illegal. Close, but not over the line. You are not using this to access an uninitialized member, you are using it to take the uninitialized member's address. Which is just as much as you are allowed to do legitimately (for complete members of the same class or superclasses, but not subclasses or members of incomplete type). While not wrong, I would personally nevertheless avoid it because it makes me feel funny (legitimate as it may be).

    – Damon
    May 10 at 17:32







  • 2





    No, & with an unqualified name never creates a pointer-to-member. If you wanted a pointer-to-member, you would have to write &Klass::str. Similarly, &this->foo and &(this->foo) are the same, both create ordinary pointers because these are member-access expressions, not qualified names.

    – Ben Voigt
    May 10 at 17:50







  • 2





    The Standard rule you link to starts out with "If the operand is a qualified-id" Which is why it does not apply here.

    – Ben Voigt
    May 10 at 17:52






  • 1





    Moreover, there are no implicit conversions from a pointer-to-member type to a pointer type (what object would it bind to?).

    – Sneftel
    May 10 at 17:54















-1














Funny question.



It is legitimate and will "work", though barely. There is a little "but" related to types which makes the whole thing a bit awkward with a bad taste (but not illegitimate), and which might make it illegal some border cases involving inheritance.



You can, of course, take the address of any object whether it's initialized or not, as long as it exists in the scope and has a name which you can prepend operator& to. Dereferencing the pointer is a different thing, but that wasn't the question.



Now, the subtle problem is that the standard defines the result of operator& for non-static struct members as "“pointer to member of class C of type T” and is a prvalue designating C::m".



Which basically means that ptr_str&str will take the address of str, but the type is not pointer-to, but pointer-to-member-of. It is then implicitly and silently cast to pointer-to.



In other words, although you do not need to explicitly write &this->str, that's nevertheless what its type is -- it's what it is and what it means [1].



Is this valid, and is it safe to use it within the initializer list? Well yes, just... barely. It's safe to use it as long as it's not being used to access uninitialized members or virtual functions, directly or indirectly. Which, as it happens, is the case here (it might not be the case in a different, arguably contrieved case).





[1] Funnily, paragraph 4 starts with a clause that says that no member pointer is formed when you put stuff in parenthese. That's remarkable because most people would probably do that just to be 100% sure they got operator precedence right. But if I read correctly, then &this->foo and &(this->foo) are not in any way the same!




share|improve this answer























  • Wow, I had to read it twice. What I understood is that the code I've got there is strictly speaking illegal (since it uses this to access an uninitialized member), and it is so subtle that I'd better avoid it altogether. Is that correct?

    – Ayxan
    May 10 at 17:21







  • 1





    No, no, no. It is strictly legal. But it gets very "close" to being illegal. Close, but not over the line. You are not using this to access an uninitialized member, you are using it to take the uninitialized member's address. Which is just as much as you are allowed to do legitimately (for complete members of the same class or superclasses, but not subclasses or members of incomplete type). While not wrong, I would personally nevertheless avoid it because it makes me feel funny (legitimate as it may be).

    – Damon
    May 10 at 17:32







  • 2





    No, & with an unqualified name never creates a pointer-to-member. If you wanted a pointer-to-member, you would have to write &Klass::str. Similarly, &this->foo and &(this->foo) are the same, both create ordinary pointers because these are member-access expressions, not qualified names.

    – Ben Voigt
    May 10 at 17:50







  • 2





    The Standard rule you link to starts out with "If the operand is a qualified-id" Which is why it does not apply here.

    – Ben Voigt
    May 10 at 17:52






  • 1





    Moreover, there are no implicit conversions from a pointer-to-member type to a pointer type (what object would it bind to?).

    – Sneftel
    May 10 at 17:54













-1












-1








-1







Funny question.



It is legitimate and will "work", though barely. There is a little "but" related to types which makes the whole thing a bit awkward with a bad taste (but not illegitimate), and which might make it illegal some border cases involving inheritance.



You can, of course, take the address of any object whether it's initialized or not, as long as it exists in the scope and has a name which you can prepend operator& to. Dereferencing the pointer is a different thing, but that wasn't the question.



Now, the subtle problem is that the standard defines the result of operator& for non-static struct members as "“pointer to member of class C of type T” and is a prvalue designating C::m".



Which basically means that ptr_str&str will take the address of str, but the type is not pointer-to, but pointer-to-member-of. It is then implicitly and silently cast to pointer-to.



In other words, although you do not need to explicitly write &this->str, that's nevertheless what its type is -- it's what it is and what it means [1].



Is this valid, and is it safe to use it within the initializer list? Well yes, just... barely. It's safe to use it as long as it's not being used to access uninitialized members or virtual functions, directly or indirectly. Which, as it happens, is the case here (it might not be the case in a different, arguably contrieved case).





[1] Funnily, paragraph 4 starts with a clause that says that no member pointer is formed when you put stuff in parenthese. That's remarkable because most people would probably do that just to be 100% sure they got operator precedence right. But if I read correctly, then &this->foo and &(this->foo) are not in any way the same!




share|improve this answer













Funny question.



It is legitimate and will "work", though barely. There is a little "but" related to types which makes the whole thing a bit awkward with a bad taste (but not illegitimate), and which might make it illegal some border cases involving inheritance.



You can, of course, take the address of any object whether it's initialized or not, as long as it exists in the scope and has a name which you can prepend operator& to. Dereferencing the pointer is a different thing, but that wasn't the question.



Now, the subtle problem is that the standard defines the result of operator& for non-static struct members as "“pointer to member of class C of type T” and is a prvalue designating C::m".



Which basically means that ptr_str&str will take the address of str, but the type is not pointer-to, but pointer-to-member-of. It is then implicitly and silently cast to pointer-to.



In other words, although you do not need to explicitly write &this->str, that's nevertheless what its type is -- it's what it is and what it means [1].



Is this valid, and is it safe to use it within the initializer list? Well yes, just... barely. It's safe to use it as long as it's not being used to access uninitialized members or virtual functions, directly or indirectly. Which, as it happens, is the case here (it might not be the case in a different, arguably contrieved case).





[1] Funnily, paragraph 4 starts with a clause that says that no member pointer is formed when you put stuff in parenthese. That's remarkable because most people would probably do that just to be 100% sure they got operator precedence right. But if I read correctly, then &this->foo and &(this->foo) are not in any way the same!





share|improve this answer












share|improve this answer



share|improve this answer










answered May 10 at 17:12









DamonDamon

52.9k15104161




52.9k15104161












  • Wow, I had to read it twice. What I understood is that the code I've got there is strictly speaking illegal (since it uses this to access an uninitialized member), and it is so subtle that I'd better avoid it altogether. Is that correct?

    – Ayxan
    May 10 at 17:21







  • 1





    No, no, no. It is strictly legal. But it gets very "close" to being illegal. Close, but not over the line. You are not using this to access an uninitialized member, you are using it to take the uninitialized member's address. Which is just as much as you are allowed to do legitimately (for complete members of the same class or superclasses, but not subclasses or members of incomplete type). While not wrong, I would personally nevertheless avoid it because it makes me feel funny (legitimate as it may be).

    – Damon
    May 10 at 17:32







  • 2





    No, & with an unqualified name never creates a pointer-to-member. If you wanted a pointer-to-member, you would have to write &Klass::str. Similarly, &this->foo and &(this->foo) are the same, both create ordinary pointers because these are member-access expressions, not qualified names.

    – Ben Voigt
    May 10 at 17:50







  • 2





    The Standard rule you link to starts out with "If the operand is a qualified-id" Which is why it does not apply here.

    – Ben Voigt
    May 10 at 17:52






  • 1





    Moreover, there are no implicit conversions from a pointer-to-member type to a pointer type (what object would it bind to?).

    – Sneftel
    May 10 at 17:54

















  • Wow, I had to read it twice. What I understood is that the code I've got there is strictly speaking illegal (since it uses this to access an uninitialized member), and it is so subtle that I'd better avoid it altogether. Is that correct?

    – Ayxan
    May 10 at 17:21







  • 1





    No, no, no. It is strictly legal. But it gets very "close" to being illegal. Close, but not over the line. You are not using this to access an uninitialized member, you are using it to take the uninitialized member's address. Which is just as much as you are allowed to do legitimately (for complete members of the same class or superclasses, but not subclasses or members of incomplete type). While not wrong, I would personally nevertheless avoid it because it makes me feel funny (legitimate as it may be).

    – Damon
    May 10 at 17:32







  • 2





    No, & with an unqualified name never creates a pointer-to-member. If you wanted a pointer-to-member, you would have to write &Klass::str. Similarly, &this->foo and &(this->foo) are the same, both create ordinary pointers because these are member-access expressions, not qualified names.

    – Ben Voigt
    May 10 at 17:50







  • 2





    The Standard rule you link to starts out with "If the operand is a qualified-id" Which is why it does not apply here.

    – Ben Voigt
    May 10 at 17:52






  • 1





    Moreover, there are no implicit conversions from a pointer-to-member type to a pointer type (what object would it bind to?).

    – Sneftel
    May 10 at 17:54
















Wow, I had to read it twice. What I understood is that the code I've got there is strictly speaking illegal (since it uses this to access an uninitialized member), and it is so subtle that I'd better avoid it altogether. Is that correct?

– Ayxan
May 10 at 17:21






Wow, I had to read it twice. What I understood is that the code I've got there is strictly speaking illegal (since it uses this to access an uninitialized member), and it is so subtle that I'd better avoid it altogether. Is that correct?

– Ayxan
May 10 at 17:21





1




1





No, no, no. It is strictly legal. But it gets very "close" to being illegal. Close, but not over the line. You are not using this to access an uninitialized member, you are using it to take the uninitialized member's address. Which is just as much as you are allowed to do legitimately (for complete members of the same class or superclasses, but not subclasses or members of incomplete type). While not wrong, I would personally nevertheless avoid it because it makes me feel funny (legitimate as it may be).

– Damon
May 10 at 17:32






No, no, no. It is strictly legal. But it gets very "close" to being illegal. Close, but not over the line. You are not using this to access an uninitialized member, you are using it to take the uninitialized member's address. Which is just as much as you are allowed to do legitimately (for complete members of the same class or superclasses, but not subclasses or members of incomplete type). While not wrong, I would personally nevertheless avoid it because it makes me feel funny (legitimate as it may be).

– Damon
May 10 at 17:32





2




2





No, & with an unqualified name never creates a pointer-to-member. If you wanted a pointer-to-member, you would have to write &Klass::str. Similarly, &this->foo and &(this->foo) are the same, both create ordinary pointers because these are member-access expressions, not qualified names.

– Ben Voigt
May 10 at 17:50






No, & with an unqualified name never creates a pointer-to-member. If you wanted a pointer-to-member, you would have to write &Klass::str. Similarly, &this->foo and &(this->foo) are the same, both create ordinary pointers because these are member-access expressions, not qualified names.

– Ben Voigt
May 10 at 17:50





2




2





The Standard rule you link to starts out with "If the operand is a qualified-id" Which is why it does not apply here.

– Ben Voigt
May 10 at 17:52





The Standard rule you link to starts out with "If the operand is a qualified-id" Which is why it does not apply here.

– Ben Voigt
May 10 at 17:52




1




1





Moreover, there are no implicit conversions from a pointer-to-member type to a pointer type (what object would it bind to?).

– Sneftel
May 10 at 17:54





Moreover, there are no implicit conversions from a pointer-to-member type to a pointer type (what object would it bind to?).

– Sneftel
May 10 at 17:54

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56078944%2fdoes-a-member-have-to-be-initialized-to-take-its-address%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

Circuit construction for execution of conditional statements using least significant bitHow are two different registers being used as “control”?How exactly is the stated composite state of the two registers being produced using the $R_zz$ controlled rotations?Efficiently performing controlled rotations in HHLWould this quantum algorithm implementation work?How to prepare a superposed states of odd integers from $1$ to $sqrtN$?Why is this implementation of the order finding algorithm not working?Circuit construction for Hamiltonian simulationHow can I invert the least significant bit of a certain term of a superposed state?Implementing an oracleImplementing a controlled sum operation

Magento 2 “No Payment Methods” in Admin New OrderHow to integrate Paypal Express Checkout with the Magento APIMagento 1.5 - Sales > Order > edit order and shipping methods disappearAuto Invoice Check/Money Order Payment methodAdd more simple payment methods?Shipping methods not showingWhat should I do to change payment methods if changing the configuration has no effects?1.9 - No Payment Methods showing upMy Payment Methods not Showing for downloadable/virtual product when checkout?Magento2 API to access internal payment methodHow to call an existing payment methods in the registration form?