What's the behavior of an uninitialized variable used as its own initializer?












10















I noticed just now that the following code can be compiled with clang/gcc/clang++/g++, using c99, c11, c++11 standards.



int main(void) {
int i = i;
}


and even with -Wall -Wextra, none of the compilers even reports warnings.



By modifying the code to int i = i + 1; and with -Wall, they may report:



why.c:2:13: warning: variable 'i' is uninitialized when used within its own initialization [-Wuninitialized]
int i = i + 1;
~ ^
1 warning generated.


My questions:




  • Why is this even allowed by compilers?

  • What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?










share|improve this question




















  • 2





    There is nothing "even" in -Wall -Wextra. That's about the bare minimum in warnings. See this answer of mine to an older question about -Wall...

    – DevSolar
    12 hours ago








  • 1





    -Wall is enough for me to get a warning for gcc

    – Kevin
    11 hours ago






  • 2





    Duplicate: Why does the compiler allow initializing a variable with itself?. However, the answers there are not very good. So lets leave this open for now and see if something better comes up. Then we can close the linked post instead.

    – Lundin
    11 hours ago






  • 2





    I improved the title and will mop up some old, bad duplicates, since the answers posted here so far are already better than those posted for the dupe questions.

    – Lundin
    10 hours ago






  • 1





    The C++ part is a duplicate of stackoverflow.com/q/14935722/5376789

    – xskxzr
    10 hours ago
















10















I noticed just now that the following code can be compiled with clang/gcc/clang++/g++, using c99, c11, c++11 standards.



int main(void) {
int i = i;
}


and even with -Wall -Wextra, none of the compilers even reports warnings.



By modifying the code to int i = i + 1; and with -Wall, they may report:



why.c:2:13: warning: variable 'i' is uninitialized when used within its own initialization [-Wuninitialized]
int i = i + 1;
~ ^
1 warning generated.


My questions:




  • Why is this even allowed by compilers?

  • What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?










share|improve this question




















  • 2





    There is nothing "even" in -Wall -Wextra. That's about the bare minimum in warnings. See this answer of mine to an older question about -Wall...

    – DevSolar
    12 hours ago








  • 1





    -Wall is enough for me to get a warning for gcc

    – Kevin
    11 hours ago






  • 2





    Duplicate: Why does the compiler allow initializing a variable with itself?. However, the answers there are not very good. So lets leave this open for now and see if something better comes up. Then we can close the linked post instead.

    – Lundin
    11 hours ago






  • 2





    I improved the title and will mop up some old, bad duplicates, since the answers posted here so far are already better than those posted for the dupe questions.

    – Lundin
    10 hours ago






  • 1





    The C++ part is a duplicate of stackoverflow.com/q/14935722/5376789

    – xskxzr
    10 hours ago














10












10








10


1






I noticed just now that the following code can be compiled with clang/gcc/clang++/g++, using c99, c11, c++11 standards.



int main(void) {
int i = i;
}


and even with -Wall -Wextra, none of the compilers even reports warnings.



By modifying the code to int i = i + 1; and with -Wall, they may report:



why.c:2:13: warning: variable 'i' is uninitialized when used within its own initialization [-Wuninitialized]
int i = i + 1;
~ ^
1 warning generated.


My questions:




  • Why is this even allowed by compilers?

  • What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?










share|improve this question
















I noticed just now that the following code can be compiled with clang/gcc/clang++/g++, using c99, c11, c++11 standards.



int main(void) {
int i = i;
}


and even with -Wall -Wextra, none of the compilers even reports warnings.



By modifying the code to int i = i + 1; and with -Wall, they may report:



why.c:2:13: warning: variable 'i' is uninitialized when used within its own initialization [-Wuninitialized]
int i = i + 1;
~ ^
1 warning generated.


My questions:




  • Why is this even allowed by compilers?

  • What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?







c++ c initialization language-lawyer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 10 hours ago









Lundin

107k17158262




107k17158262










asked 12 hours ago









Hongxu ChenHongxu Chen

2,6172867




2,6172867








  • 2





    There is nothing "even" in -Wall -Wextra. That's about the bare minimum in warnings. See this answer of mine to an older question about -Wall...

    – DevSolar
    12 hours ago








  • 1





    -Wall is enough for me to get a warning for gcc

    – Kevin
    11 hours ago






  • 2





    Duplicate: Why does the compiler allow initializing a variable with itself?. However, the answers there are not very good. So lets leave this open for now and see if something better comes up. Then we can close the linked post instead.

    – Lundin
    11 hours ago






  • 2





    I improved the title and will mop up some old, bad duplicates, since the answers posted here so far are already better than those posted for the dupe questions.

    – Lundin
    10 hours ago






  • 1





    The C++ part is a duplicate of stackoverflow.com/q/14935722/5376789

    – xskxzr
    10 hours ago














  • 2





    There is nothing "even" in -Wall -Wextra. That's about the bare minimum in warnings. See this answer of mine to an older question about -Wall...

    – DevSolar
    12 hours ago








  • 1





    -Wall is enough for me to get a warning for gcc

    – Kevin
    11 hours ago






  • 2





    Duplicate: Why does the compiler allow initializing a variable with itself?. However, the answers there are not very good. So lets leave this open for now and see if something better comes up. Then we can close the linked post instead.

    – Lundin
    11 hours ago






  • 2





    I improved the title and will mop up some old, bad duplicates, since the answers posted here so far are already better than those posted for the dupe questions.

    – Lundin
    10 hours ago






  • 1





    The C++ part is a duplicate of stackoverflow.com/q/14935722/5376789

    – xskxzr
    10 hours ago








2




2





There is nothing "even" in -Wall -Wextra. That's about the bare minimum in warnings. See this answer of mine to an older question about -Wall...

– DevSolar
12 hours ago







There is nothing "even" in -Wall -Wextra. That's about the bare minimum in warnings. See this answer of mine to an older question about -Wall...

– DevSolar
12 hours ago






1




1





-Wall is enough for me to get a warning for gcc

– Kevin
11 hours ago





-Wall is enough for me to get a warning for gcc

– Kevin
11 hours ago




2




2





Duplicate: Why does the compiler allow initializing a variable with itself?. However, the answers there are not very good. So lets leave this open for now and see if something better comes up. Then we can close the linked post instead.

– Lundin
11 hours ago





Duplicate: Why does the compiler allow initializing a variable with itself?. However, the answers there are not very good. So lets leave this open for now and see if something better comes up. Then we can close the linked post instead.

– Lundin
11 hours ago




2




2





I improved the title and will mop up some old, bad duplicates, since the answers posted here so far are already better than those posted for the dupe questions.

– Lundin
10 hours ago





I improved the title and will mop up some old, bad duplicates, since the answers posted here so far are already better than those posted for the dupe questions.

– Lundin
10 hours ago




1




1





The C++ part is a duplicate of stackoverflow.com/q/14935722/5376789

– xskxzr
10 hours ago





The C++ part is a duplicate of stackoverflow.com/q/14935722/5376789

– xskxzr
10 hours ago












3 Answers
3






active

oldest

votes


















10














Because i is uninitialized when use to initialize itself, it has an indeterminate value at that time. An indeterminate value can be either an unspecified value or a trap representation.



If your implementation supports padding bits in integer types and if the indeterminate value in question happens to be a trap representation, then using it results in undefined behavior.



If your implementation does not have padding in integers, then the value is simply unspecified and there is no undefined behavior.



EDIT:



To elaborate further, the behavior can still be undefined if i never has its address taken at some point. This is detailed in section 6.3.2.1p2 of the C11 standard:




If the lvalue designates an object of automatic storage
duration that could have been declared with the register storage
class (never had its address taken), and that object is uninitialized
(not declared with an initializer and no assignment to it
has been performed prior to use), the behavior is undefined.




So if you never take the address of i, then you have undefined behavior. Otherwise, the statements above apply.






share|improve this answer


























  • It is perhaps relevant to include that the scope of identifier i begins at the end of its declarator, of which the initializer is not part. Thus i is in scope in its own initializer, even though it is not useful to initialize it with itself.

    – John Bollinger
    11 hours ago













  • Also, there's a bit of a wiggly issue around C11 6.3.2.1/2, though I don't think that makes your analysis incorrect.

    – John Bollinger
    11 hours ago











  • Can you elaborate this, better with reference to the standard?

    – Hongxu Chen
    11 hours ago











  • @JohnBollinger This answer is essentially correct. The complete story including the 6.3.2.1 special case can be found here: (Why) is using an uninitialized variable undefined behavior?

    – Lundin
    10 hours ago






  • 1





    @JohnBollinger Added further detail on whether i had its address taken.

    – dbush
    10 hours ago



















8














This is a warning, it's not related to the standard.



Warnings are heuristic with "optimistic" approach. The warning is issued only when the compiler is sure that it's going to be a problem. In cases like this you have better luck with clang or newest versions of gcc as stated in comments (see another related question of mine: why am I not getting an "used uninitialized" warning from gcc in this trivial example?).



anyway, in the first case:



int i = i;


does nothing, since i==i already. It is possible that the assignment is completely optimized out as it's useless. With compilers which don't "see" self-initialization as a problem you can do this without a warning:



int i = i;
printf("%dn",i);


Whereas this triggers a warning all right:



int i;
printf("%dn",i);


Still, it's bad enough not to be warned about this, since from now on i is seen as initialized.



In the second case:



int i = i + 1;


A computation between an uninitialized value and 1 must be performed. Undefined behaviour happens there.






share|improve this answer





















  • 1





    Good answer; however, I am not sure about the "warnings issued, when the compiler is sure that there is going to be a problem". There are many warnings, where this isn't the case, this is highly dependent on the warning types enabled

    – Ctx
    12 hours ago






  • 1





    The risk with int i = i + 1 is that UB is UB, period. Also, signed overflow. Also, much scratching of heads when another coder has to make sense of that code at some later point.

    – DevSolar
    11 hours ago











  • true! I forgot the sign. Edited out to make it simple

    – Jean-François Fabre
    11 hours ago











  • As @Ctx says. For example, I often find myself building third-party code that causes tons of warnings about use of possibly uninitialized variables. Control-flow analysis in those cases normally shows that the programmer included appropriate logic to ensure that the variable is assigned a value before its value is used. But the compiler is explicitly unsure whether there is a problem.

    – John Bollinger
    11 hours ago













  • -Wparentheses would be another example.

    – Osiris
    11 hours ago



















2














I believe you are okay with getting the warning in case of



int i = i + 1; 


as expected, however, you expect the warning to be displayed even in case of



int i = i;


also.




Why is this even allowed by compilers?




There is nothing inherently wrong with the statement. See the related discussions:





  • Why does the compiler allow initializing a variable with itself?


  • Why is initialization of a new variable by itself valid?


for more insight.




What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?




This is undefined behavior, as the type int can have trap representation and you never have taken the address of the variable in discussion. So, technically, you'll face UB as soon as you try to use the (indeterminate) value stored in variable i.



You should turn on your compiler warnings. In gcc,





  • compile with -Winit-self to get a warning. in C.


  • For C++, -Winit-self is enabled with -Wall already.






share|improve this answer


























  • no dice with -Winit-self either here, using gcc 7.3.1

    – Jean-François Fabre
    12 hours ago











  • @Jean-FrançoisFabre I get that

    – Sourav Ghosh
    11 hours ago











  • you have a new version of gcc. Mine is older. When you say "probable source of undefined behavior (if the value of the variable is used later on)" it's the same as using it uninitialized.

    – Jean-François Fabre
    11 hours 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%2f54200465%2fwhats-the-behavior-of-an-uninitialized-variable-used-as-its-own-initializer%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









10














Because i is uninitialized when use to initialize itself, it has an indeterminate value at that time. An indeterminate value can be either an unspecified value or a trap representation.



If your implementation supports padding bits in integer types and if the indeterminate value in question happens to be a trap representation, then using it results in undefined behavior.



If your implementation does not have padding in integers, then the value is simply unspecified and there is no undefined behavior.



EDIT:



To elaborate further, the behavior can still be undefined if i never has its address taken at some point. This is detailed in section 6.3.2.1p2 of the C11 standard:




If the lvalue designates an object of automatic storage
duration that could have been declared with the register storage
class (never had its address taken), and that object is uninitialized
(not declared with an initializer and no assignment to it
has been performed prior to use), the behavior is undefined.




So if you never take the address of i, then you have undefined behavior. Otherwise, the statements above apply.






share|improve this answer


























  • It is perhaps relevant to include that the scope of identifier i begins at the end of its declarator, of which the initializer is not part. Thus i is in scope in its own initializer, even though it is not useful to initialize it with itself.

    – John Bollinger
    11 hours ago













  • Also, there's a bit of a wiggly issue around C11 6.3.2.1/2, though I don't think that makes your analysis incorrect.

    – John Bollinger
    11 hours ago











  • Can you elaborate this, better with reference to the standard?

    – Hongxu Chen
    11 hours ago











  • @JohnBollinger This answer is essentially correct. The complete story including the 6.3.2.1 special case can be found here: (Why) is using an uninitialized variable undefined behavior?

    – Lundin
    10 hours ago






  • 1





    @JohnBollinger Added further detail on whether i had its address taken.

    – dbush
    10 hours ago
















10














Because i is uninitialized when use to initialize itself, it has an indeterminate value at that time. An indeterminate value can be either an unspecified value or a trap representation.



If your implementation supports padding bits in integer types and if the indeterminate value in question happens to be a trap representation, then using it results in undefined behavior.



If your implementation does not have padding in integers, then the value is simply unspecified and there is no undefined behavior.



EDIT:



To elaborate further, the behavior can still be undefined if i never has its address taken at some point. This is detailed in section 6.3.2.1p2 of the C11 standard:




If the lvalue designates an object of automatic storage
duration that could have been declared with the register storage
class (never had its address taken), and that object is uninitialized
(not declared with an initializer and no assignment to it
has been performed prior to use), the behavior is undefined.




So if you never take the address of i, then you have undefined behavior. Otherwise, the statements above apply.






share|improve this answer


























  • It is perhaps relevant to include that the scope of identifier i begins at the end of its declarator, of which the initializer is not part. Thus i is in scope in its own initializer, even though it is not useful to initialize it with itself.

    – John Bollinger
    11 hours ago













  • Also, there's a bit of a wiggly issue around C11 6.3.2.1/2, though I don't think that makes your analysis incorrect.

    – John Bollinger
    11 hours ago











  • Can you elaborate this, better with reference to the standard?

    – Hongxu Chen
    11 hours ago











  • @JohnBollinger This answer is essentially correct. The complete story including the 6.3.2.1 special case can be found here: (Why) is using an uninitialized variable undefined behavior?

    – Lundin
    10 hours ago






  • 1





    @JohnBollinger Added further detail on whether i had its address taken.

    – dbush
    10 hours ago














10












10








10







Because i is uninitialized when use to initialize itself, it has an indeterminate value at that time. An indeterminate value can be either an unspecified value or a trap representation.



If your implementation supports padding bits in integer types and if the indeterminate value in question happens to be a trap representation, then using it results in undefined behavior.



If your implementation does not have padding in integers, then the value is simply unspecified and there is no undefined behavior.



EDIT:



To elaborate further, the behavior can still be undefined if i never has its address taken at some point. This is detailed in section 6.3.2.1p2 of the C11 standard:




If the lvalue designates an object of automatic storage
duration that could have been declared with the register storage
class (never had its address taken), and that object is uninitialized
(not declared with an initializer and no assignment to it
has been performed prior to use), the behavior is undefined.




So if you never take the address of i, then you have undefined behavior. Otherwise, the statements above apply.






share|improve this answer















Because i is uninitialized when use to initialize itself, it has an indeterminate value at that time. An indeterminate value can be either an unspecified value or a trap representation.



If your implementation supports padding bits in integer types and if the indeterminate value in question happens to be a trap representation, then using it results in undefined behavior.



If your implementation does not have padding in integers, then the value is simply unspecified and there is no undefined behavior.



EDIT:



To elaborate further, the behavior can still be undefined if i never has its address taken at some point. This is detailed in section 6.3.2.1p2 of the C11 standard:




If the lvalue designates an object of automatic storage
duration that could have been declared with the register storage
class (never had its address taken), and that object is uninitialized
(not declared with an initializer and no assignment to it
has been performed prior to use), the behavior is undefined.




So if you never take the address of i, then you have undefined behavior. Otherwise, the statements above apply.







share|improve this answer














share|improve this answer



share|improve this answer








edited 10 hours ago

























answered 11 hours ago









dbushdbush

94.1k12101135




94.1k12101135













  • It is perhaps relevant to include that the scope of identifier i begins at the end of its declarator, of which the initializer is not part. Thus i is in scope in its own initializer, even though it is not useful to initialize it with itself.

    – John Bollinger
    11 hours ago













  • Also, there's a bit of a wiggly issue around C11 6.3.2.1/2, though I don't think that makes your analysis incorrect.

    – John Bollinger
    11 hours ago











  • Can you elaborate this, better with reference to the standard?

    – Hongxu Chen
    11 hours ago











  • @JohnBollinger This answer is essentially correct. The complete story including the 6.3.2.1 special case can be found here: (Why) is using an uninitialized variable undefined behavior?

    – Lundin
    10 hours ago






  • 1





    @JohnBollinger Added further detail on whether i had its address taken.

    – dbush
    10 hours ago



















  • It is perhaps relevant to include that the scope of identifier i begins at the end of its declarator, of which the initializer is not part. Thus i is in scope in its own initializer, even though it is not useful to initialize it with itself.

    – John Bollinger
    11 hours ago













  • Also, there's a bit of a wiggly issue around C11 6.3.2.1/2, though I don't think that makes your analysis incorrect.

    – John Bollinger
    11 hours ago











  • Can you elaborate this, better with reference to the standard?

    – Hongxu Chen
    11 hours ago











  • @JohnBollinger This answer is essentially correct. The complete story including the 6.3.2.1 special case can be found here: (Why) is using an uninitialized variable undefined behavior?

    – Lundin
    10 hours ago






  • 1





    @JohnBollinger Added further detail on whether i had its address taken.

    – dbush
    10 hours ago

















It is perhaps relevant to include that the scope of identifier i begins at the end of its declarator, of which the initializer is not part. Thus i is in scope in its own initializer, even though it is not useful to initialize it with itself.

– John Bollinger
11 hours ago







It is perhaps relevant to include that the scope of identifier i begins at the end of its declarator, of which the initializer is not part. Thus i is in scope in its own initializer, even though it is not useful to initialize it with itself.

– John Bollinger
11 hours ago















Also, there's a bit of a wiggly issue around C11 6.3.2.1/2, though I don't think that makes your analysis incorrect.

– John Bollinger
11 hours ago





Also, there's a bit of a wiggly issue around C11 6.3.2.1/2, though I don't think that makes your analysis incorrect.

– John Bollinger
11 hours ago













Can you elaborate this, better with reference to the standard?

– Hongxu Chen
11 hours ago





Can you elaborate this, better with reference to the standard?

– Hongxu Chen
11 hours ago













@JohnBollinger This answer is essentially correct. The complete story including the 6.3.2.1 special case can be found here: (Why) is using an uninitialized variable undefined behavior?

– Lundin
10 hours ago





@JohnBollinger This answer is essentially correct. The complete story including the 6.3.2.1 special case can be found here: (Why) is using an uninitialized variable undefined behavior?

– Lundin
10 hours ago




1




1





@JohnBollinger Added further detail on whether i had its address taken.

– dbush
10 hours ago





@JohnBollinger Added further detail on whether i had its address taken.

– dbush
10 hours ago













8














This is a warning, it's not related to the standard.



Warnings are heuristic with "optimistic" approach. The warning is issued only when the compiler is sure that it's going to be a problem. In cases like this you have better luck with clang or newest versions of gcc as stated in comments (see another related question of mine: why am I not getting an "used uninitialized" warning from gcc in this trivial example?).



anyway, in the first case:



int i = i;


does nothing, since i==i already. It is possible that the assignment is completely optimized out as it's useless. With compilers which don't "see" self-initialization as a problem you can do this without a warning:



int i = i;
printf("%dn",i);


Whereas this triggers a warning all right:



int i;
printf("%dn",i);


Still, it's bad enough not to be warned about this, since from now on i is seen as initialized.



In the second case:



int i = i + 1;


A computation between an uninitialized value and 1 must be performed. Undefined behaviour happens there.






share|improve this answer





















  • 1





    Good answer; however, I am not sure about the "warnings issued, when the compiler is sure that there is going to be a problem". There are many warnings, where this isn't the case, this is highly dependent on the warning types enabled

    – Ctx
    12 hours ago






  • 1





    The risk with int i = i + 1 is that UB is UB, period. Also, signed overflow. Also, much scratching of heads when another coder has to make sense of that code at some later point.

    – DevSolar
    11 hours ago











  • true! I forgot the sign. Edited out to make it simple

    – Jean-François Fabre
    11 hours ago











  • As @Ctx says. For example, I often find myself building third-party code that causes tons of warnings about use of possibly uninitialized variables. Control-flow analysis in those cases normally shows that the programmer included appropriate logic to ensure that the variable is assigned a value before its value is used. But the compiler is explicitly unsure whether there is a problem.

    – John Bollinger
    11 hours ago













  • -Wparentheses would be another example.

    – Osiris
    11 hours ago
















8














This is a warning, it's not related to the standard.



Warnings are heuristic with "optimistic" approach. The warning is issued only when the compiler is sure that it's going to be a problem. In cases like this you have better luck with clang or newest versions of gcc as stated in comments (see another related question of mine: why am I not getting an "used uninitialized" warning from gcc in this trivial example?).



anyway, in the first case:



int i = i;


does nothing, since i==i already. It is possible that the assignment is completely optimized out as it's useless. With compilers which don't "see" self-initialization as a problem you can do this without a warning:



int i = i;
printf("%dn",i);


Whereas this triggers a warning all right:



int i;
printf("%dn",i);


Still, it's bad enough not to be warned about this, since from now on i is seen as initialized.



In the second case:



int i = i + 1;


A computation between an uninitialized value and 1 must be performed. Undefined behaviour happens there.






share|improve this answer





















  • 1





    Good answer; however, I am not sure about the "warnings issued, when the compiler is sure that there is going to be a problem". There are many warnings, where this isn't the case, this is highly dependent on the warning types enabled

    – Ctx
    12 hours ago






  • 1





    The risk with int i = i + 1 is that UB is UB, period. Also, signed overflow. Also, much scratching of heads when another coder has to make sense of that code at some later point.

    – DevSolar
    11 hours ago











  • true! I forgot the sign. Edited out to make it simple

    – Jean-François Fabre
    11 hours ago











  • As @Ctx says. For example, I often find myself building third-party code that causes tons of warnings about use of possibly uninitialized variables. Control-flow analysis in those cases normally shows that the programmer included appropriate logic to ensure that the variable is assigned a value before its value is used. But the compiler is explicitly unsure whether there is a problem.

    – John Bollinger
    11 hours ago













  • -Wparentheses would be another example.

    – Osiris
    11 hours ago














8












8








8







This is a warning, it's not related to the standard.



Warnings are heuristic with "optimistic" approach. The warning is issued only when the compiler is sure that it's going to be a problem. In cases like this you have better luck with clang or newest versions of gcc as stated in comments (see another related question of mine: why am I not getting an "used uninitialized" warning from gcc in this trivial example?).



anyway, in the first case:



int i = i;


does nothing, since i==i already. It is possible that the assignment is completely optimized out as it's useless. With compilers which don't "see" self-initialization as a problem you can do this without a warning:



int i = i;
printf("%dn",i);


Whereas this triggers a warning all right:



int i;
printf("%dn",i);


Still, it's bad enough not to be warned about this, since from now on i is seen as initialized.



In the second case:



int i = i + 1;


A computation between an uninitialized value and 1 must be performed. Undefined behaviour happens there.






share|improve this answer















This is a warning, it's not related to the standard.



Warnings are heuristic with "optimistic" approach. The warning is issued only when the compiler is sure that it's going to be a problem. In cases like this you have better luck with clang or newest versions of gcc as stated in comments (see another related question of mine: why am I not getting an "used uninitialized" warning from gcc in this trivial example?).



anyway, in the first case:



int i = i;


does nothing, since i==i already. It is possible that the assignment is completely optimized out as it's useless. With compilers which don't "see" self-initialization as a problem you can do this without a warning:



int i = i;
printf("%dn",i);


Whereas this triggers a warning all right:



int i;
printf("%dn",i);


Still, it's bad enough not to be warned about this, since from now on i is seen as initialized.



In the second case:



int i = i + 1;


A computation between an uninitialized value and 1 must be performed. Undefined behaviour happens there.







share|improve this answer














share|improve this answer



share|improve this answer








edited 11 hours ago

























answered 12 hours ago









Jean-François FabreJean-François Fabre

102k954109




102k954109








  • 1





    Good answer; however, I am not sure about the "warnings issued, when the compiler is sure that there is going to be a problem". There are many warnings, where this isn't the case, this is highly dependent on the warning types enabled

    – Ctx
    12 hours ago






  • 1





    The risk with int i = i + 1 is that UB is UB, period. Also, signed overflow. Also, much scratching of heads when another coder has to make sense of that code at some later point.

    – DevSolar
    11 hours ago











  • true! I forgot the sign. Edited out to make it simple

    – Jean-François Fabre
    11 hours ago











  • As @Ctx says. For example, I often find myself building third-party code that causes tons of warnings about use of possibly uninitialized variables. Control-flow analysis in those cases normally shows that the programmer included appropriate logic to ensure that the variable is assigned a value before its value is used. But the compiler is explicitly unsure whether there is a problem.

    – John Bollinger
    11 hours ago













  • -Wparentheses would be another example.

    – Osiris
    11 hours ago














  • 1





    Good answer; however, I am not sure about the "warnings issued, when the compiler is sure that there is going to be a problem". There are many warnings, where this isn't the case, this is highly dependent on the warning types enabled

    – Ctx
    12 hours ago






  • 1





    The risk with int i = i + 1 is that UB is UB, period. Also, signed overflow. Also, much scratching of heads when another coder has to make sense of that code at some later point.

    – DevSolar
    11 hours ago











  • true! I forgot the sign. Edited out to make it simple

    – Jean-François Fabre
    11 hours ago











  • As @Ctx says. For example, I often find myself building third-party code that causes tons of warnings about use of possibly uninitialized variables. Control-flow analysis in those cases normally shows that the programmer included appropriate logic to ensure that the variable is assigned a value before its value is used. But the compiler is explicitly unsure whether there is a problem.

    – John Bollinger
    11 hours ago













  • -Wparentheses would be another example.

    – Osiris
    11 hours ago








1




1





Good answer; however, I am not sure about the "warnings issued, when the compiler is sure that there is going to be a problem". There are many warnings, where this isn't the case, this is highly dependent on the warning types enabled

– Ctx
12 hours ago





Good answer; however, I am not sure about the "warnings issued, when the compiler is sure that there is going to be a problem". There are many warnings, where this isn't the case, this is highly dependent on the warning types enabled

– Ctx
12 hours ago




1




1





The risk with int i = i + 1 is that UB is UB, period. Also, signed overflow. Also, much scratching of heads when another coder has to make sense of that code at some later point.

– DevSolar
11 hours ago





The risk with int i = i + 1 is that UB is UB, period. Also, signed overflow. Also, much scratching of heads when another coder has to make sense of that code at some later point.

– DevSolar
11 hours ago













true! I forgot the sign. Edited out to make it simple

– Jean-François Fabre
11 hours ago





true! I forgot the sign. Edited out to make it simple

– Jean-François Fabre
11 hours ago













As @Ctx says. For example, I often find myself building third-party code that causes tons of warnings about use of possibly uninitialized variables. Control-flow analysis in those cases normally shows that the programmer included appropriate logic to ensure that the variable is assigned a value before its value is used. But the compiler is explicitly unsure whether there is a problem.

– John Bollinger
11 hours ago







As @Ctx says. For example, I often find myself building third-party code that causes tons of warnings about use of possibly uninitialized variables. Control-flow analysis in those cases normally shows that the programmer included appropriate logic to ensure that the variable is assigned a value before its value is used. But the compiler is explicitly unsure whether there is a problem.

– John Bollinger
11 hours ago















-Wparentheses would be another example.

– Osiris
11 hours ago





-Wparentheses would be another example.

– Osiris
11 hours ago











2














I believe you are okay with getting the warning in case of



int i = i + 1; 


as expected, however, you expect the warning to be displayed even in case of



int i = i;


also.




Why is this even allowed by compilers?




There is nothing inherently wrong with the statement. See the related discussions:





  • Why does the compiler allow initializing a variable with itself?


  • Why is initialization of a new variable by itself valid?


for more insight.




What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?




This is undefined behavior, as the type int can have trap representation and you never have taken the address of the variable in discussion. So, technically, you'll face UB as soon as you try to use the (indeterminate) value stored in variable i.



You should turn on your compiler warnings. In gcc,





  • compile with -Winit-self to get a warning. in C.


  • For C++, -Winit-self is enabled with -Wall already.






share|improve this answer


























  • no dice with -Winit-self either here, using gcc 7.3.1

    – Jean-François Fabre
    12 hours ago











  • @Jean-FrançoisFabre I get that

    – Sourav Ghosh
    11 hours ago











  • you have a new version of gcc. Mine is older. When you say "probable source of undefined behavior (if the value of the variable is used later on)" it's the same as using it uninitialized.

    – Jean-François Fabre
    11 hours ago


















2














I believe you are okay with getting the warning in case of



int i = i + 1; 


as expected, however, you expect the warning to be displayed even in case of



int i = i;


also.




Why is this even allowed by compilers?




There is nothing inherently wrong with the statement. See the related discussions:





  • Why does the compiler allow initializing a variable with itself?


  • Why is initialization of a new variable by itself valid?


for more insight.




What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?




This is undefined behavior, as the type int can have trap representation and you never have taken the address of the variable in discussion. So, technically, you'll face UB as soon as you try to use the (indeterminate) value stored in variable i.



You should turn on your compiler warnings. In gcc,





  • compile with -Winit-self to get a warning. in C.


  • For C++, -Winit-self is enabled with -Wall already.






share|improve this answer


























  • no dice with -Winit-self either here, using gcc 7.3.1

    – Jean-François Fabre
    12 hours ago











  • @Jean-FrançoisFabre I get that

    – Sourav Ghosh
    11 hours ago











  • you have a new version of gcc. Mine is older. When you say "probable source of undefined behavior (if the value of the variable is used later on)" it's the same as using it uninitialized.

    – Jean-François Fabre
    11 hours ago
















2












2








2







I believe you are okay with getting the warning in case of



int i = i + 1; 


as expected, however, you expect the warning to be displayed even in case of



int i = i;


also.




Why is this even allowed by compilers?




There is nothing inherently wrong with the statement. See the related discussions:





  • Why does the compiler allow initializing a variable with itself?


  • Why is initialization of a new variable by itself valid?


for more insight.




What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?




This is undefined behavior, as the type int can have trap representation and you never have taken the address of the variable in discussion. So, technically, you'll face UB as soon as you try to use the (indeterminate) value stored in variable i.



You should turn on your compiler warnings. In gcc,





  • compile with -Winit-self to get a warning. in C.


  • For C++, -Winit-self is enabled with -Wall already.






share|improve this answer















I believe you are okay with getting the warning in case of



int i = i + 1; 


as expected, however, you expect the warning to be displayed even in case of



int i = i;


also.




Why is this even allowed by compilers?




There is nothing inherently wrong with the statement. See the related discussions:





  • Why does the compiler allow initializing a variable with itself?


  • Why is initialization of a new variable by itself valid?


for more insight.




What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?




This is undefined behavior, as the type int can have trap representation and you never have taken the address of the variable in discussion. So, technically, you'll face UB as soon as you try to use the (indeterminate) value stored in variable i.



You should turn on your compiler warnings. In gcc,





  • compile with -Winit-self to get a warning. in C.


  • For C++, -Winit-self is enabled with -Wall already.







share|improve this answer














share|improve this answer



share|improve this answer








edited 10 hours ago

























answered 12 hours ago









Sourav GhoshSourav Ghosh

109k14129188




109k14129188













  • no dice with -Winit-self either here, using gcc 7.3.1

    – Jean-François Fabre
    12 hours ago











  • @Jean-FrançoisFabre I get that

    – Sourav Ghosh
    11 hours ago











  • you have a new version of gcc. Mine is older. When you say "probable source of undefined behavior (if the value of the variable is used later on)" it's the same as using it uninitialized.

    – Jean-François Fabre
    11 hours ago





















  • no dice with -Winit-self either here, using gcc 7.3.1

    – Jean-François Fabre
    12 hours ago











  • @Jean-FrançoisFabre I get that

    – Sourav Ghosh
    11 hours ago











  • you have a new version of gcc. Mine is older. When you say "probable source of undefined behavior (if the value of the variable is used later on)" it's the same as using it uninitialized.

    – Jean-François Fabre
    11 hours ago



















no dice with -Winit-self either here, using gcc 7.3.1

– Jean-François Fabre
12 hours ago





no dice with -Winit-self either here, using gcc 7.3.1

– Jean-François Fabre
12 hours ago













@Jean-FrançoisFabre I get that

– Sourav Ghosh
11 hours ago





@Jean-FrançoisFabre I get that

– Sourav Ghosh
11 hours ago













you have a new version of gcc. Mine is older. When you say "probable source of undefined behavior (if the value of the variable is used later on)" it's the same as using it uninitialized.

– Jean-François Fabre
11 hours ago







you have a new version of gcc. Mine is older. When you say "probable source of undefined behavior (if the value of the variable is used later on)" it's the same as using it uninitialized.

– Jean-François Fabre
11 hours 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%2f54200465%2fwhats-the-behavior-of-an-uninitialized-variable-used-as-its-own-initializer%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

香粉寮

GameSpot