C's equality operator on converted pointers Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Casting integer constant to a pointer typeWhat are the differences between a pointer variable and a reference variable in C++?What is a smart pointer and when should I use one?How do function pointers in C work?What does the C ??!??! operator do?Why should I use a pointer rather than the object itself?How to determine if a pointer equals an element of an array?Comparing pointer values after conversion, still same equality?Equality comparison of pointers to different objectsCan an equality comparison of unrelated pointers evaluate to true?Identically-valued pointers comparing unequal

Maximum summed subsequences with non-adjacent items

Do wooden building fires get hotter than 600°C?

Where is the Data Import Wizard Error Log

Sentence with dass with three Verbs (One modal and two connected with zu)

How fail-safe is nr as stop bytes?

How do living politicians protect their readily obtainable signatures from misuse?

Lagrange four-squares theorem --- deterministic complexity

Random body shuffle every night—can we still function?

What order were files/directories output in dir?

What to do with repeated rejections for phd position

Antipodal Land Area Calculation

Putting class ranking in CV, but against dept guidelines

What does Turing mean by this statement?

The Nth Gryphon Number

What is "gratricide"?

Dyck paths with extra diagonals from valleys (Laser construction)

How to dry out epoxy resin faster than usual?

How to write capital alpha?

How to run automated tests after each commit?

What initially awakened the Balrog?

Most bit efficient text communication method?

What is Adi Shankara referring to when he says "He has Vajra marks on his feet"?

Would it be easier to apply for a UK visa if there is a host family to sponsor for you in going there?

What are the discoveries that have been possible with the rejection of positivism?



C's equality operator on converted pointers



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Casting integer constant to a pointer typeWhat are the differences between a pointer variable and a reference variable in C++?What is a smart pointer and when should I use one?How do function pointers in C work?What does the C ??!??! operator do?Why should I use a pointer rather than the object itself?How to determine if a pointer equals an element of an array?Comparing pointer values after conversion, still same equality?Equality comparison of pointers to different objectsCan an equality comparison of unrelated pointers evaluate to true?Identically-valued pointers comparing unequal



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








8















Coming from Casting integer constant to a pointer type



From that question, we know from 6.3.2.3p5 (C11) that we can convert any integer into a pointer (i.e. it is not UB on itself):




An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.




Then, from 6.5.9p6, we have:




Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.




So it seems we can apply the equality operator here with no UB (unlike the relational operators). Consider:



struct A;

int f(void)
struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return a == b;



Assuming there is no A object in a's address 1, one could argue that f() should return false, because no condition matches the above.



How is this refuted? Does "pointer to the same object" refer to addresses, even if no objects are there (not like the compiler could know, anyway)? Should we simply understand that it is implementation-defined since the previous results were already implementation-defined? Where does the standard specify this?



All major compilers return true for the above code, as one would expect.










share|improve this question
























  • What is "Except as previously specified" referring to? That might be important. Also, as far as Trap Representation is concerned, is it referring to the object supposedly pointed to, or is it referring to the pointer itself having trap representation perhaps as a result of misalignment?

    – Christian Gibbons
    4 hours ago












  • They appeared to compare equal coliru.stacked-crooked.com/a/0ca45c3b900ade34 even with -O3. Strange...

    – St.Antario
    4 hours ago







  • 3





    @ChristianGibbons That refers to the null pointer constant case.

    – Acorn
    4 hours ago

















8















Coming from Casting integer constant to a pointer type



From that question, we know from 6.3.2.3p5 (C11) that we can convert any integer into a pointer (i.e. it is not UB on itself):




An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.




Then, from 6.5.9p6, we have:




Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.




So it seems we can apply the equality operator here with no UB (unlike the relational operators). Consider:



struct A;

int f(void)
struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return a == b;



Assuming there is no A object in a's address 1, one could argue that f() should return false, because no condition matches the above.



How is this refuted? Does "pointer to the same object" refer to addresses, even if no objects are there (not like the compiler could know, anyway)? Should we simply understand that it is implementation-defined since the previous results were already implementation-defined? Where does the standard specify this?



All major compilers return true for the above code, as one would expect.










share|improve this question
























  • What is "Except as previously specified" referring to? That might be important. Also, as far as Trap Representation is concerned, is it referring to the object supposedly pointed to, or is it referring to the pointer itself having trap representation perhaps as a result of misalignment?

    – Christian Gibbons
    4 hours ago












  • They appeared to compare equal coliru.stacked-crooked.com/a/0ca45c3b900ade34 even with -O3. Strange...

    – St.Antario
    4 hours ago







  • 3





    @ChristianGibbons That refers to the null pointer constant case.

    – Acorn
    4 hours ago













8












8








8


3






Coming from Casting integer constant to a pointer type



From that question, we know from 6.3.2.3p5 (C11) that we can convert any integer into a pointer (i.e. it is not UB on itself):




An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.




Then, from 6.5.9p6, we have:




Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.




So it seems we can apply the equality operator here with no UB (unlike the relational operators). Consider:



struct A;

int f(void)
struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return a == b;



Assuming there is no A object in a's address 1, one could argue that f() should return false, because no condition matches the above.



How is this refuted? Does "pointer to the same object" refer to addresses, even if no objects are there (not like the compiler could know, anyway)? Should we simply understand that it is implementation-defined since the previous results were already implementation-defined? Where does the standard specify this?



All major compilers return true for the above code, as one would expect.










share|improve this question
















Coming from Casting integer constant to a pointer type



From that question, we know from 6.3.2.3p5 (C11) that we can convert any integer into a pointer (i.e. it is not UB on itself):




An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.




Then, from 6.5.9p6, we have:




Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.




So it seems we can apply the equality operator here with no UB (unlike the relational operators). Consider:



struct A;

int f(void)
struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return a == b;



Assuming there is no A object in a's address 1, one could argue that f() should return false, because no condition matches the above.



How is this refuted? Does "pointer to the same object" refer to addresses, even if no objects are there (not like the compiler could know, anyway)? Should we simply understand that it is implementation-defined since the previous results were already implementation-defined? Where does the standard specify this?



All major compilers return true for the above code, as one would expect.







c pointers language-lawyer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 4 hours ago







Acorn

















asked 4 hours ago









AcornAcorn

6,70611441




6,70611441












  • What is "Except as previously specified" referring to? That might be important. Also, as far as Trap Representation is concerned, is it referring to the object supposedly pointed to, or is it referring to the pointer itself having trap representation perhaps as a result of misalignment?

    – Christian Gibbons
    4 hours ago












  • They appeared to compare equal coliru.stacked-crooked.com/a/0ca45c3b900ade34 even with -O3. Strange...

    – St.Antario
    4 hours ago







  • 3





    @ChristianGibbons That refers to the null pointer constant case.

    – Acorn
    4 hours ago

















  • What is "Except as previously specified" referring to? That might be important. Also, as far as Trap Representation is concerned, is it referring to the object supposedly pointed to, or is it referring to the pointer itself having trap representation perhaps as a result of misalignment?

    – Christian Gibbons
    4 hours ago












  • They appeared to compare equal coliru.stacked-crooked.com/a/0ca45c3b900ade34 even with -O3. Strange...

    – St.Antario
    4 hours ago







  • 3





    @ChristianGibbons That refers to the null pointer constant case.

    – Acorn
    4 hours ago
















What is "Except as previously specified" referring to? That might be important. Also, as far as Trap Representation is concerned, is it referring to the object supposedly pointed to, or is it referring to the pointer itself having trap representation perhaps as a result of misalignment?

– Christian Gibbons
4 hours ago






What is "Except as previously specified" referring to? That might be important. Also, as far as Trap Representation is concerned, is it referring to the object supposedly pointed to, or is it referring to the pointer itself having trap representation perhaps as a result of misalignment?

– Christian Gibbons
4 hours ago














They appeared to compare equal coliru.stacked-crooked.com/a/0ca45c3b900ade34 even with -O3. Strange...

– St.Antario
4 hours ago






They appeared to compare equal coliru.stacked-crooked.com/a/0ca45c3b900ade34 even with -O3. Strange...

– St.Antario
4 hours ago





3




3





@ChristianGibbons That refers to the null pointer constant case.

– Acorn
4 hours ago





@ChristianGibbons That refers to the null pointer constant case.

– Acorn
4 hours ago












5 Answers
5






active

oldest

votes


















3















How is this refuted? Does "pointer to the same object" refer to
addresses, even if no objects are there




No, I don't think that would be a plausible reading. If you stipulate that the pointer value is not a pointer to an object (and if it is not a null pointer) then an equality comparison of that (pointer) value with itself does not satisfy the "only if" condition of 6.5.9/6, and therefore the comparison must evaluate to 0.



But not so fast. Who says that (struct A *) 1 is not a pointer to an object?
Consider the Standard's definition of "object":




object

region of data storage in the execution environment, the contents of
which can represent values




(C 2011, 3.15/1)



Note that the definition is not inherently limited to objects that are allocated or declared by the program. To the best of my knowledge, the standard nowhere limits the scope of the term in that way. It does define means to allocate objects, but it does not specify that objects allocated in one of those ways are the only ones that exist. Thus, implementations are free to interpret that pointer value as a pointer to an object, in which case the equality comparison may evaluate to 1.



It also might still not evaluate to 1, as despite the two pointers (presumably) having bitwise-identical representations, they are not necessarily considered pointers to the same object.




(not like the compiler could
know, anyway)?




Of course the compiler could and should know. It has to know in order to evaluate expressions such as you present. The most straightforward approach -- and, not coincidentally, the most common -- is to interpret every non-null pointer value that is not a trap representation as a pointer to an object.




Should we simply understand that it is
implementation-defined since the previous results were already
implementation-defined?




Being implementation-defined carries a requirement for conforming implementations to document their choice. The behavior you're asking about may follow from the implementation-defined behavior of converting an integer to a pointer, but it is not implementation-defined itself.




Where does the standard specify this?




It does not specify. In principle, conforming implementations may differ on this point. In practice, however, they're pretty consistent.






share|improve this answer




















  • 2





    Note also the Committee response to C defect report 260, in which the Committee holds that "[Implementations] may also treat pointers based on different origins as distinct even though they are bitwise identical." That could be taken as applying to the example case, so again, the standard does not specify.

    – John Bollinger
    1 hour ago












  • In this live example however this is exactly the case. -O2 yields different addresses btw which is not really clear to me...

    – St.Antario
    36 mins ago












  • Which "this" is exactly what case? And are you claiming that's inconsistent with this answer?

    – John Bollinger
    34 mins ago












  • I meant two pointers with the same address did not compare equal... no?

    – St.Antario
    33 mins ago






  • 1





    That the example exhibits different behavior with different optimization levels does not prove that the code has UB. The same can happen if it has behavior that is merely unspecified, as that code does.

    – John Bollinger
    29 mins ago


















2














Constraint violation




An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation. C17dr §6.3.2.3 5




With (struct A *) 1 code attempts the conversion. The result is implementation-defined, may lack alignment, ... might be a trap.



Next code tries to initialize a below.



struct A * a = (struct A *) 1;


Initialization constraints include:




No initializer shall attempt to provide a value for an object not contained within the entity being initialized. §6.7.9 2




It is not defined that (struct A *) 1 meets that constraint.






share|improve this answer


















  • 1





    I'm having great difficulty accepting your application of 6.7.9.2. From what I can see, the initializer is providing a value for the whole of a, which is utterly routine. I don't think that provision has anything to do with limiting the value specified. What it forbids is declarations like this: struct int a; x = .b = 1 ;, on account of the entity being declared, x, not having a member named b.

    – John Bollinger
    1 hour ago



















1














This comparison between 2 pointers to arbitrary objects is implementation defined.



Not every architecture allow the pointers to any possible integer value. Not every architecture is able to keep a pointer that represents the location 1000 (or whatever integer), maybe because its assembly language miss such a feature. The C language does not impose any representation for a memory location -- on some architectures the address 1000 may have no meaning.



A detailed discussion is here. In this detailed explanation you can see a concrete example so:




Note that the pointers p and q point to the same memory address. Still the expression p == q evaluates to false which is very surprising at first. 







share|improve this answer




















  • 2





    The OP's comparison certainly is not implementation defined, but it is implementation dependent. The distinction is in whether conforming implementations are required to document their choice.

    – John Bollinger
    1 hour ago


















0














Strictly speaking, this is undefined behavior because neither a nor b point to an object and (most likely) the converted values are not properly aligned.



This however should be OK:



struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return (int)a == (int)b;


Since you convert an integer to a pointer and back again to get the original value.






share|improve this answer


















  • 5





    But what exactly in the standard makes it UB?

    – PSkocik
    3 hours ago


















0















Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function




Both a and b refer to the same (invalid) memory address i.e. 0x1

Hence they are equal. The quotation does not mean that the referred objects are equal per se, but that the memory addresses refer to the same location






share|improve this answer




















  • 1





    The committee has officially rejected the proposition that two pointers having identical bit patterns must necessarily compare equal (see DR 260).

    – John Bollinger
    1 hour ago











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%2f55764953%2fcs-equality-operator-on-converted-pointers%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























5 Answers
5






active

oldest

votes








5 Answers
5






active

oldest

votes









active

oldest

votes






active

oldest

votes









3















How is this refuted? Does "pointer to the same object" refer to
addresses, even if no objects are there




No, I don't think that would be a plausible reading. If you stipulate that the pointer value is not a pointer to an object (and if it is not a null pointer) then an equality comparison of that (pointer) value with itself does not satisfy the "only if" condition of 6.5.9/6, and therefore the comparison must evaluate to 0.



But not so fast. Who says that (struct A *) 1 is not a pointer to an object?
Consider the Standard's definition of "object":




object

region of data storage in the execution environment, the contents of
which can represent values




(C 2011, 3.15/1)



Note that the definition is not inherently limited to objects that are allocated or declared by the program. To the best of my knowledge, the standard nowhere limits the scope of the term in that way. It does define means to allocate objects, but it does not specify that objects allocated in one of those ways are the only ones that exist. Thus, implementations are free to interpret that pointer value as a pointer to an object, in which case the equality comparison may evaluate to 1.



It also might still not evaluate to 1, as despite the two pointers (presumably) having bitwise-identical representations, they are not necessarily considered pointers to the same object.




(not like the compiler could
know, anyway)?




Of course the compiler could and should know. It has to know in order to evaluate expressions such as you present. The most straightforward approach -- and, not coincidentally, the most common -- is to interpret every non-null pointer value that is not a trap representation as a pointer to an object.




Should we simply understand that it is
implementation-defined since the previous results were already
implementation-defined?




Being implementation-defined carries a requirement for conforming implementations to document their choice. The behavior you're asking about may follow from the implementation-defined behavior of converting an integer to a pointer, but it is not implementation-defined itself.




Where does the standard specify this?




It does not specify. In principle, conforming implementations may differ on this point. In practice, however, they're pretty consistent.






share|improve this answer




















  • 2





    Note also the Committee response to C defect report 260, in which the Committee holds that "[Implementations] may also treat pointers based on different origins as distinct even though they are bitwise identical." That could be taken as applying to the example case, so again, the standard does not specify.

    – John Bollinger
    1 hour ago












  • In this live example however this is exactly the case. -O2 yields different addresses btw which is not really clear to me...

    – St.Antario
    36 mins ago












  • Which "this" is exactly what case? And are you claiming that's inconsistent with this answer?

    – John Bollinger
    34 mins ago












  • I meant two pointers with the same address did not compare equal... no?

    – St.Antario
    33 mins ago






  • 1





    That the example exhibits different behavior with different optimization levels does not prove that the code has UB. The same can happen if it has behavior that is merely unspecified, as that code does.

    – John Bollinger
    29 mins ago















3















How is this refuted? Does "pointer to the same object" refer to
addresses, even if no objects are there




No, I don't think that would be a plausible reading. If you stipulate that the pointer value is not a pointer to an object (and if it is not a null pointer) then an equality comparison of that (pointer) value with itself does not satisfy the "only if" condition of 6.5.9/6, and therefore the comparison must evaluate to 0.



But not so fast. Who says that (struct A *) 1 is not a pointer to an object?
Consider the Standard's definition of "object":




object

region of data storage in the execution environment, the contents of
which can represent values




(C 2011, 3.15/1)



Note that the definition is not inherently limited to objects that are allocated or declared by the program. To the best of my knowledge, the standard nowhere limits the scope of the term in that way. It does define means to allocate objects, but it does not specify that objects allocated in one of those ways are the only ones that exist. Thus, implementations are free to interpret that pointer value as a pointer to an object, in which case the equality comparison may evaluate to 1.



It also might still not evaluate to 1, as despite the two pointers (presumably) having bitwise-identical representations, they are not necessarily considered pointers to the same object.




(not like the compiler could
know, anyway)?




Of course the compiler could and should know. It has to know in order to evaluate expressions such as you present. The most straightforward approach -- and, not coincidentally, the most common -- is to interpret every non-null pointer value that is not a trap representation as a pointer to an object.




Should we simply understand that it is
implementation-defined since the previous results were already
implementation-defined?




Being implementation-defined carries a requirement for conforming implementations to document their choice. The behavior you're asking about may follow from the implementation-defined behavior of converting an integer to a pointer, but it is not implementation-defined itself.




Where does the standard specify this?




It does not specify. In principle, conforming implementations may differ on this point. In practice, however, they're pretty consistent.






share|improve this answer




















  • 2





    Note also the Committee response to C defect report 260, in which the Committee holds that "[Implementations] may also treat pointers based on different origins as distinct even though they are bitwise identical." That could be taken as applying to the example case, so again, the standard does not specify.

    – John Bollinger
    1 hour ago












  • In this live example however this is exactly the case. -O2 yields different addresses btw which is not really clear to me...

    – St.Antario
    36 mins ago












  • Which "this" is exactly what case? And are you claiming that's inconsistent with this answer?

    – John Bollinger
    34 mins ago












  • I meant two pointers with the same address did not compare equal... no?

    – St.Antario
    33 mins ago






  • 1





    That the example exhibits different behavior with different optimization levels does not prove that the code has UB. The same can happen if it has behavior that is merely unspecified, as that code does.

    – John Bollinger
    29 mins ago













3












3








3








How is this refuted? Does "pointer to the same object" refer to
addresses, even if no objects are there




No, I don't think that would be a plausible reading. If you stipulate that the pointer value is not a pointer to an object (and if it is not a null pointer) then an equality comparison of that (pointer) value with itself does not satisfy the "only if" condition of 6.5.9/6, and therefore the comparison must evaluate to 0.



But not so fast. Who says that (struct A *) 1 is not a pointer to an object?
Consider the Standard's definition of "object":




object

region of data storage in the execution environment, the contents of
which can represent values




(C 2011, 3.15/1)



Note that the definition is not inherently limited to objects that are allocated or declared by the program. To the best of my knowledge, the standard nowhere limits the scope of the term in that way. It does define means to allocate objects, but it does not specify that objects allocated in one of those ways are the only ones that exist. Thus, implementations are free to interpret that pointer value as a pointer to an object, in which case the equality comparison may evaluate to 1.



It also might still not evaluate to 1, as despite the two pointers (presumably) having bitwise-identical representations, they are not necessarily considered pointers to the same object.




(not like the compiler could
know, anyway)?




Of course the compiler could and should know. It has to know in order to evaluate expressions such as you present. The most straightforward approach -- and, not coincidentally, the most common -- is to interpret every non-null pointer value that is not a trap representation as a pointer to an object.




Should we simply understand that it is
implementation-defined since the previous results were already
implementation-defined?




Being implementation-defined carries a requirement for conforming implementations to document their choice. The behavior you're asking about may follow from the implementation-defined behavior of converting an integer to a pointer, but it is not implementation-defined itself.




Where does the standard specify this?




It does not specify. In principle, conforming implementations may differ on this point. In practice, however, they're pretty consistent.






share|improve this answer
















How is this refuted? Does "pointer to the same object" refer to
addresses, even if no objects are there




No, I don't think that would be a plausible reading. If you stipulate that the pointer value is not a pointer to an object (and if it is not a null pointer) then an equality comparison of that (pointer) value with itself does not satisfy the "only if" condition of 6.5.9/6, and therefore the comparison must evaluate to 0.



But not so fast. Who says that (struct A *) 1 is not a pointer to an object?
Consider the Standard's definition of "object":




object

region of data storage in the execution environment, the contents of
which can represent values




(C 2011, 3.15/1)



Note that the definition is not inherently limited to objects that are allocated or declared by the program. To the best of my knowledge, the standard nowhere limits the scope of the term in that way. It does define means to allocate objects, but it does not specify that objects allocated in one of those ways are the only ones that exist. Thus, implementations are free to interpret that pointer value as a pointer to an object, in which case the equality comparison may evaluate to 1.



It also might still not evaluate to 1, as despite the two pointers (presumably) having bitwise-identical representations, they are not necessarily considered pointers to the same object.




(not like the compiler could
know, anyway)?




Of course the compiler could and should know. It has to know in order to evaluate expressions such as you present. The most straightforward approach -- and, not coincidentally, the most common -- is to interpret every non-null pointer value that is not a trap representation as a pointer to an object.




Should we simply understand that it is
implementation-defined since the previous results were already
implementation-defined?




Being implementation-defined carries a requirement for conforming implementations to document their choice. The behavior you're asking about may follow from the implementation-defined behavior of converting an integer to a pointer, but it is not implementation-defined itself.




Where does the standard specify this?




It does not specify. In principle, conforming implementations may differ on this point. In practice, however, they're pretty consistent.







share|improve this answer














share|improve this answer



share|improve this answer








edited 40 mins ago

























answered 2 hours ago









John BollingerJohn Bollinger

86k74280




86k74280







  • 2





    Note also the Committee response to C defect report 260, in which the Committee holds that "[Implementations] may also treat pointers based on different origins as distinct even though they are bitwise identical." That could be taken as applying to the example case, so again, the standard does not specify.

    – John Bollinger
    1 hour ago












  • In this live example however this is exactly the case. -O2 yields different addresses btw which is not really clear to me...

    – St.Antario
    36 mins ago












  • Which "this" is exactly what case? And are you claiming that's inconsistent with this answer?

    – John Bollinger
    34 mins ago












  • I meant two pointers with the same address did not compare equal... no?

    – St.Antario
    33 mins ago






  • 1





    That the example exhibits different behavior with different optimization levels does not prove that the code has UB. The same can happen if it has behavior that is merely unspecified, as that code does.

    – John Bollinger
    29 mins ago












  • 2





    Note also the Committee response to C defect report 260, in which the Committee holds that "[Implementations] may also treat pointers based on different origins as distinct even though they are bitwise identical." That could be taken as applying to the example case, so again, the standard does not specify.

    – John Bollinger
    1 hour ago












  • In this live example however this is exactly the case. -O2 yields different addresses btw which is not really clear to me...

    – St.Antario
    36 mins ago












  • Which "this" is exactly what case? And are you claiming that's inconsistent with this answer?

    – John Bollinger
    34 mins ago












  • I meant two pointers with the same address did not compare equal... no?

    – St.Antario
    33 mins ago






  • 1





    That the example exhibits different behavior with different optimization levels does not prove that the code has UB. The same can happen if it has behavior that is merely unspecified, as that code does.

    – John Bollinger
    29 mins ago







2




2





Note also the Committee response to C defect report 260, in which the Committee holds that "[Implementations] may also treat pointers based on different origins as distinct even though they are bitwise identical." That could be taken as applying to the example case, so again, the standard does not specify.

– John Bollinger
1 hour ago






Note also the Committee response to C defect report 260, in which the Committee holds that "[Implementations] may also treat pointers based on different origins as distinct even though they are bitwise identical." That could be taken as applying to the example case, so again, the standard does not specify.

– John Bollinger
1 hour ago














In this live example however this is exactly the case. -O2 yields different addresses btw which is not really clear to me...

– St.Antario
36 mins ago






In this live example however this is exactly the case. -O2 yields different addresses btw which is not really clear to me...

– St.Antario
36 mins ago














Which "this" is exactly what case? And are you claiming that's inconsistent with this answer?

– John Bollinger
34 mins ago






Which "this" is exactly what case? And are you claiming that's inconsistent with this answer?

– John Bollinger
34 mins ago














I meant two pointers with the same address did not compare equal... no?

– St.Antario
33 mins ago





I meant two pointers with the same address did not compare equal... no?

– St.Antario
33 mins ago




1




1





That the example exhibits different behavior with different optimization levels does not prove that the code has UB. The same can happen if it has behavior that is merely unspecified, as that code does.

– John Bollinger
29 mins ago





That the example exhibits different behavior with different optimization levels does not prove that the code has UB. The same can happen if it has behavior that is merely unspecified, as that code does.

– John Bollinger
29 mins ago













2














Constraint violation




An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation. C17dr §6.3.2.3 5




With (struct A *) 1 code attempts the conversion. The result is implementation-defined, may lack alignment, ... might be a trap.



Next code tries to initialize a below.



struct A * a = (struct A *) 1;


Initialization constraints include:




No initializer shall attempt to provide a value for an object not contained within the entity being initialized. §6.7.9 2




It is not defined that (struct A *) 1 meets that constraint.






share|improve this answer


















  • 1





    I'm having great difficulty accepting your application of 6.7.9.2. From what I can see, the initializer is providing a value for the whole of a, which is utterly routine. I don't think that provision has anything to do with limiting the value specified. What it forbids is declarations like this: struct int a; x = .b = 1 ;, on account of the entity being declared, x, not having a member named b.

    – John Bollinger
    1 hour ago
















2














Constraint violation




An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation. C17dr §6.3.2.3 5




With (struct A *) 1 code attempts the conversion. The result is implementation-defined, may lack alignment, ... might be a trap.



Next code tries to initialize a below.



struct A * a = (struct A *) 1;


Initialization constraints include:




No initializer shall attempt to provide a value for an object not contained within the entity being initialized. §6.7.9 2




It is not defined that (struct A *) 1 meets that constraint.






share|improve this answer


















  • 1





    I'm having great difficulty accepting your application of 6.7.9.2. From what I can see, the initializer is providing a value for the whole of a, which is utterly routine. I don't think that provision has anything to do with limiting the value specified. What it forbids is declarations like this: struct int a; x = .b = 1 ;, on account of the entity being declared, x, not having a member named b.

    – John Bollinger
    1 hour ago














2












2








2







Constraint violation




An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation. C17dr §6.3.2.3 5




With (struct A *) 1 code attempts the conversion. The result is implementation-defined, may lack alignment, ... might be a trap.



Next code tries to initialize a below.



struct A * a = (struct A *) 1;


Initialization constraints include:




No initializer shall attempt to provide a value for an object not contained within the entity being initialized. §6.7.9 2




It is not defined that (struct A *) 1 meets that constraint.






share|improve this answer













Constraint violation




An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation. C17dr §6.3.2.3 5




With (struct A *) 1 code attempts the conversion. The result is implementation-defined, may lack alignment, ... might be a trap.



Next code tries to initialize a below.



struct A * a = (struct A *) 1;


Initialization constraints include:




No initializer shall attempt to provide a value for an object not contained within the entity being initialized. §6.7.9 2




It is not defined that (struct A *) 1 meets that constraint.







share|improve this answer












share|improve this answer



share|improve this answer










answered 1 hour ago









chuxchux

85.4k874158




85.4k874158







  • 1





    I'm having great difficulty accepting your application of 6.7.9.2. From what I can see, the initializer is providing a value for the whole of a, which is utterly routine. I don't think that provision has anything to do with limiting the value specified. What it forbids is declarations like this: struct int a; x = .b = 1 ;, on account of the entity being declared, x, not having a member named b.

    – John Bollinger
    1 hour ago













  • 1





    I'm having great difficulty accepting your application of 6.7.9.2. From what I can see, the initializer is providing a value for the whole of a, which is utterly routine. I don't think that provision has anything to do with limiting the value specified. What it forbids is declarations like this: struct int a; x = .b = 1 ;, on account of the entity being declared, x, not having a member named b.

    – John Bollinger
    1 hour ago








1




1





I'm having great difficulty accepting your application of 6.7.9.2. From what I can see, the initializer is providing a value for the whole of a, which is utterly routine. I don't think that provision has anything to do with limiting the value specified. What it forbids is declarations like this: struct int a; x = .b = 1 ;, on account of the entity being declared, x, not having a member named b.

– John Bollinger
1 hour ago






I'm having great difficulty accepting your application of 6.7.9.2. From what I can see, the initializer is providing a value for the whole of a, which is utterly routine. I don't think that provision has anything to do with limiting the value specified. What it forbids is declarations like this: struct int a; x = .b = 1 ;, on account of the entity being declared, x, not having a member named b.

– John Bollinger
1 hour ago












1














This comparison between 2 pointers to arbitrary objects is implementation defined.



Not every architecture allow the pointers to any possible integer value. Not every architecture is able to keep a pointer that represents the location 1000 (or whatever integer), maybe because its assembly language miss such a feature. The C language does not impose any representation for a memory location -- on some architectures the address 1000 may have no meaning.



A detailed discussion is here. In this detailed explanation you can see a concrete example so:




Note that the pointers p and q point to the same memory address. Still the expression p == q evaluates to false which is very surprising at first. 







share|improve this answer




















  • 2





    The OP's comparison certainly is not implementation defined, but it is implementation dependent. The distinction is in whether conforming implementations are required to document their choice.

    – John Bollinger
    1 hour ago















1














This comparison between 2 pointers to arbitrary objects is implementation defined.



Not every architecture allow the pointers to any possible integer value. Not every architecture is able to keep a pointer that represents the location 1000 (or whatever integer), maybe because its assembly language miss such a feature. The C language does not impose any representation for a memory location -- on some architectures the address 1000 may have no meaning.



A detailed discussion is here. In this detailed explanation you can see a concrete example so:




Note that the pointers p and q point to the same memory address. Still the expression p == q evaluates to false which is very surprising at first. 







share|improve this answer




















  • 2





    The OP's comparison certainly is not implementation defined, but it is implementation dependent. The distinction is in whether conforming implementations are required to document their choice.

    – John Bollinger
    1 hour ago













1












1








1







This comparison between 2 pointers to arbitrary objects is implementation defined.



Not every architecture allow the pointers to any possible integer value. Not every architecture is able to keep a pointer that represents the location 1000 (or whatever integer), maybe because its assembly language miss such a feature. The C language does not impose any representation for a memory location -- on some architectures the address 1000 may have no meaning.



A detailed discussion is here. In this detailed explanation you can see a concrete example so:




Note that the pointers p and q point to the same memory address. Still the expression p == q evaluates to false which is very surprising at first. 







share|improve this answer















This comparison between 2 pointers to arbitrary objects is implementation defined.



Not every architecture allow the pointers to any possible integer value. Not every architecture is able to keep a pointer that represents the location 1000 (or whatever integer), maybe because its assembly language miss such a feature. The C language does not impose any representation for a memory location -- on some architectures the address 1000 may have no meaning.



A detailed discussion is here. In this detailed explanation you can see a concrete example so:




Note that the pointers p and q point to the same memory address. Still the expression p == q evaluates to false which is very surprising at first. 








share|improve this answer














share|improve this answer



share|improve this answer








edited 1 hour ago

























answered 3 hours ago









alinsoaralinsoar

9,39513354




9,39513354







  • 2





    The OP's comparison certainly is not implementation defined, but it is implementation dependent. The distinction is in whether conforming implementations are required to document their choice.

    – John Bollinger
    1 hour ago












  • 2





    The OP's comparison certainly is not implementation defined, but it is implementation dependent. The distinction is in whether conforming implementations are required to document their choice.

    – John Bollinger
    1 hour ago







2




2





The OP's comparison certainly is not implementation defined, but it is implementation dependent. The distinction is in whether conforming implementations are required to document their choice.

– John Bollinger
1 hour ago





The OP's comparison certainly is not implementation defined, but it is implementation dependent. The distinction is in whether conforming implementations are required to document their choice.

– John Bollinger
1 hour ago











0














Strictly speaking, this is undefined behavior because neither a nor b point to an object and (most likely) the converted values are not properly aligned.



This however should be OK:



struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return (int)a == (int)b;


Since you convert an integer to a pointer and back again to get the original value.






share|improve this answer


















  • 5





    But what exactly in the standard makes it UB?

    – PSkocik
    3 hours ago















0














Strictly speaking, this is undefined behavior because neither a nor b point to an object and (most likely) the converted values are not properly aligned.



This however should be OK:



struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return (int)a == (int)b;


Since you convert an integer to a pointer and back again to get the original value.






share|improve this answer


















  • 5





    But what exactly in the standard makes it UB?

    – PSkocik
    3 hours ago













0












0








0







Strictly speaking, this is undefined behavior because neither a nor b point to an object and (most likely) the converted values are not properly aligned.



This however should be OK:



struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return (int)a == (int)b;


Since you convert an integer to a pointer and back again to get the original value.






share|improve this answer













Strictly speaking, this is undefined behavior because neither a nor b point to an object and (most likely) the converted values are not properly aligned.



This however should be OK:



struct A * a = (struct A *) 1;
struct A * b = (struct A *) 1;
return (int)a == (int)b;


Since you convert an integer to a pointer and back again to get the original value.







share|improve this answer












share|improve this answer



share|improve this answer










answered 3 hours ago









dbushdbush

105k14110148




105k14110148







  • 5





    But what exactly in the standard makes it UB?

    – PSkocik
    3 hours ago












  • 5





    But what exactly in the standard makes it UB?

    – PSkocik
    3 hours ago







5




5





But what exactly in the standard makes it UB?

– PSkocik
3 hours ago





But what exactly in the standard makes it UB?

– PSkocik
3 hours ago











0















Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function




Both a and b refer to the same (invalid) memory address i.e. 0x1

Hence they are equal. The quotation does not mean that the referred objects are equal per se, but that the memory addresses refer to the same location






share|improve this answer




















  • 1





    The committee has officially rejected the proposition that two pointers having identical bit patterns must necessarily compare equal (see DR 260).

    – John Bollinger
    1 hour ago















0















Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function




Both a and b refer to the same (invalid) memory address i.e. 0x1

Hence they are equal. The quotation does not mean that the referred objects are equal per se, but that the memory addresses refer to the same location






share|improve this answer




















  • 1





    The committee has officially rejected the proposition that two pointers having identical bit patterns must necessarily compare equal (see DR 260).

    – John Bollinger
    1 hour ago













0












0








0








Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function




Both a and b refer to the same (invalid) memory address i.e. 0x1

Hence they are equal. The quotation does not mean that the referred objects are equal per se, but that the memory addresses refer to the same location






share|improve this answer
















Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function




Both a and b refer to the same (invalid) memory address i.e. 0x1

Hence they are equal. The quotation does not mean that the referred objects are equal per se, but that the memory addresses refer to the same location







share|improve this answer














share|improve this answer



share|improve this answer








edited 3 hours ago

























answered 3 hours ago









CratylusCratylus

34k53177301




34k53177301







  • 1





    The committee has officially rejected the proposition that two pointers having identical bit patterns must necessarily compare equal (see DR 260).

    – John Bollinger
    1 hour ago












  • 1





    The committee has officially rejected the proposition that two pointers having identical bit patterns must necessarily compare equal (see DR 260).

    – John Bollinger
    1 hour ago







1




1





The committee has officially rejected the proposition that two pointers having identical bit patterns must necessarily compare equal (see DR 260).

– John Bollinger
1 hour ago





The committee has officially rejected the proposition that two pointers having identical bit patterns must necessarily compare equal (see DR 260).

– John Bollinger
1 hour ago

















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%2f55764953%2fcs-equality-operator-on-converted-pointers%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

Bett Inhaltsverzeichnis Geschichte | Bettformen | Bettgrößen | Andere Bezeichnungen | Bettenmangel | Betten in der bildenden Kunst | Schlafmedizinische Gesichtspunkte | Siehe auch | Literatur | Weblinks | Einzelnachweise | NavigationsmenüBett, Bettstatt, BettstelleCommons: BettBabybetten: Anwendung, Ausstattungsmerkmale und VergleichskriterienWasserbetten. Vorurteile im TestHapfnNursch10.1007/s11818-012-0584-74006250-8AKS4329276-8

Luksemburg Sisukord Nimi | Asend | Loodus | Riigikord | Haldusjaotus | Rahvastik | Riigikaitse | Majandus | Taristu | Ajalugu | Eesti ja Luksemburgi suhted | Haridus | Kultuur | Vaata ka | Viited | Välislingid | Navigeerimismenüü50° N, 6° EÜlevaade Luksemburgi kaitsealadest.Luksemburgi rahvaarv. Statistikaamet.World Bank'i andmebaasÜlevaade Luksemburgi loodusest.Ülevaade Luksemburgi metsadest.Guy Colling. "Red List of the Vascular Plants of Luxembourg." Travaux scientifiques du Musée national d’histoire naturelle Luxembourg. 2005.Luxembourg’s biodiversity at risk.Maailma kahepaiksete andmebaas.Denis Lepage. "Luxembourg." Avibase.Ülevaade temperatuuridest. Luksemburgi meteoroloogiateenistus.Ülevaade Luksemburgist. Euroopa Liidu esinduse koduleht.Système politique. TerritoireÜlevaade Luksemburgi rahvastikust. Luksemburgi statistikaamet.Luksemburgi rahvastik. Luksemburgi statistikaamet.The World FactbookMonique Borsenberger, Paul Dickes. "Religions au Luxembourg. Quelle évolution entre 1999-2008". Luksemburgi statistikaamet. 2011.Luksemburgi peapiiskopkond. Catholic-Hierarchy.Luksemburgi armee koduleht.Luksemburgi armee relvastus.Eesti Välisministeerium.Luksemburgi rahvastik. Luksemburgi statistikaamet.Luksemburgi Eesti Seltsi koduleht.Helen Eelrand. "Raadio, mis muutis maailma." Eesti Päevaleht. 13. märts 2004.Ülevaade Luksemburgi haridussüsteemist.Ülevaade Luksemburgi keskkoolidest.Luksemburgr

Valle di Casies Indice Geografia fisica | Origini del nome | Storia | Società | Amministrazione | Sport | Note | Bibliografia | Voci correlate | Altri progetti | Collegamenti esterni | Menu di navigazione46°46′N 12°11′E / 46.766667°N 12.183333°E46.766667; 12.183333 (Valle di Casies)46°46′N 12°11′E / 46.766667°N 12.183333°E46.766667; 12.183333 (Valle di Casies)Sito istituzionaleAstat Censimento della popolazione 2011 - Determinazione della consistenza dei tre gruppi linguistici della Provincia Autonoma di Bolzano-Alto Adige - giugno 2012Numeri e fattiValle di CasiesDato IstatTabella dei gradi/giorno dei Comuni italiani raggruppati per Regione e Provincia26 agosto 1993, n. 412Heraldry of the World: GsiesStatistiche I.StatValCasies.comWikimedia CommonsWikimedia CommonsValle di CasiesSito ufficialeValle di CasiesMM14870458910042978-6