How are errors (not related to syntax) managed in arduino and in the AVR architecture in general?











up vote
2
down vote

favorite












I was just curious about how the AVR architecture manages errors that would cause a regular desktop program to crash. I'm talking about logical errors for example math problems that are undefined. Such as division by 0 and getting a square root of a negative number. At first I was expecting that by giving an error to the AVR chip it will just return 0. But I ran this program:



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


and got this output:



4294967295
0


After this I got really confused. Why would the result variable take the maximum value of an unsigned long? Since I declared an int the micro controller must have dedicated 2 bytes of dynamic memory to this variable but apparently it somehow managed to get additional 2 bytes to store the data. Could this mean that the AVR chip can corrupt data in other memory locations while allocating new data for the variable that just was fed a undefined in to it? Okay maybe the AVR chip just sets any mathematical nonsense to 4294967295. But no in the example of getting the square root of -10 we see that the value became 0. Although this is probably a function processed by some library so maybe there is some kind of protection against these errors. Also, I tried to run the program above but with a byte variable for the result instead of int.



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


And the result was the same. So, is there some kind of documentation about error management in AVR since this is important to know while development.



P.S. Everything was run on a real Atmega 328p chip on an arduino nano.










share|improve this question
























  • I think the standard is that it is undefined for integer math. The floating point is according to the IEEE standard and returns a nan, but no exception. Catching an exeption in the Arduino is not possible (I think) : stackoverflow.com/questions/10095591/… When you find strange things with a byte, please give a full sketch that we can try and tell us which arduino board you use.
    – Jot
    8 hours ago












  • @Jot This is an interesting point but why would a nan be replaced with 4294967295. Apparently they don't have the same binary value. Why did Atmel not include a nan value (that maybe could be disabled through fuses) in their processor architecture. This is a useful troubleshooting feature that is heavily used in all major programming languages.
    – Coder_fox
    8 hours ago










  • @Jot I used an Arduino nano with an Atmega 328p on board.
    – Coder_fox
    8 hours ago










  • An integer can not be a 'nan', that is specified for floating point. Please update your question with board and microcontroller, and perhaps a full sketch.
    – Jot
    8 hours ago










  • I tried to make a sketch myself, and I have different results. Please show your sketch and tell us the results of the sketch that you show. Are you running this in a simulator?
    – Jot
    8 hours ago

















up vote
2
down vote

favorite












I was just curious about how the AVR architecture manages errors that would cause a regular desktop program to crash. I'm talking about logical errors for example math problems that are undefined. Such as division by 0 and getting a square root of a negative number. At first I was expecting that by giving an error to the AVR chip it will just return 0. But I ran this program:



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


and got this output:



4294967295
0


After this I got really confused. Why would the result variable take the maximum value of an unsigned long? Since I declared an int the micro controller must have dedicated 2 bytes of dynamic memory to this variable but apparently it somehow managed to get additional 2 bytes to store the data. Could this mean that the AVR chip can corrupt data in other memory locations while allocating new data for the variable that just was fed a undefined in to it? Okay maybe the AVR chip just sets any mathematical nonsense to 4294967295. But no in the example of getting the square root of -10 we see that the value became 0. Although this is probably a function processed by some library so maybe there is some kind of protection against these errors. Also, I tried to run the program above but with a byte variable for the result instead of int.



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


And the result was the same. So, is there some kind of documentation about error management in AVR since this is important to know while development.



P.S. Everything was run on a real Atmega 328p chip on an arduino nano.










share|improve this question
























  • I think the standard is that it is undefined for integer math. The floating point is according to the IEEE standard and returns a nan, but no exception. Catching an exeption in the Arduino is not possible (I think) : stackoverflow.com/questions/10095591/… When you find strange things with a byte, please give a full sketch that we can try and tell us which arduino board you use.
    – Jot
    8 hours ago












  • @Jot This is an interesting point but why would a nan be replaced with 4294967295. Apparently they don't have the same binary value. Why did Atmel not include a nan value (that maybe could be disabled through fuses) in their processor architecture. This is a useful troubleshooting feature that is heavily used in all major programming languages.
    – Coder_fox
    8 hours ago










  • @Jot I used an Arduino nano with an Atmega 328p on board.
    – Coder_fox
    8 hours ago










  • An integer can not be a 'nan', that is specified for floating point. Please update your question with board and microcontroller, and perhaps a full sketch.
    – Jot
    8 hours ago










  • I tried to make a sketch myself, and I have different results. Please show your sketch and tell us the results of the sketch that you show. Are you running this in a simulator?
    – Jot
    8 hours ago















up vote
2
down vote

favorite









up vote
2
down vote

favorite











I was just curious about how the AVR architecture manages errors that would cause a regular desktop program to crash. I'm talking about logical errors for example math problems that are undefined. Such as division by 0 and getting a square root of a negative number. At first I was expecting that by giving an error to the AVR chip it will just return 0. But I ran this program:



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


and got this output:



4294967295
0


After this I got really confused. Why would the result variable take the maximum value of an unsigned long? Since I declared an int the micro controller must have dedicated 2 bytes of dynamic memory to this variable but apparently it somehow managed to get additional 2 bytes to store the data. Could this mean that the AVR chip can corrupt data in other memory locations while allocating new data for the variable that just was fed a undefined in to it? Okay maybe the AVR chip just sets any mathematical nonsense to 4294967295. But no in the example of getting the square root of -10 we see that the value became 0. Although this is probably a function processed by some library so maybe there is some kind of protection against these errors. Also, I tried to run the program above but with a byte variable for the result instead of int.



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


And the result was the same. So, is there some kind of documentation about error management in AVR since this is important to know while development.



P.S. Everything was run on a real Atmega 328p chip on an arduino nano.










share|improve this question















I was just curious about how the AVR architecture manages errors that would cause a regular desktop program to crash. I'm talking about logical errors for example math problems that are undefined. Such as division by 0 and getting a square root of a negative number. At first I was expecting that by giving an error to the AVR chip it will just return 0. But I ran this program:



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


and got this output:



4294967295
0


After this I got really confused. Why would the result variable take the maximum value of an unsigned long? Since I declared an int the micro controller must have dedicated 2 bytes of dynamic memory to this variable but apparently it somehow managed to get additional 2 bytes to store the data. Could this mean that the AVR chip can corrupt data in other memory locations while allocating new data for the variable that just was fed a undefined in to it? Okay maybe the AVR chip just sets any mathematical nonsense to 4294967295. But no in the example of getting the square root of -10 we see that the value became 0. Although this is probably a function processed by some library so maybe there is some kind of protection against these errors. Also, I tried to run the program above but with a byte variable for the result instead of int.



void setup() {
Serial.begin(9600);
}
void loop(){
int x = 0;
int p = 50;
int result;
result = p/x;
Serial.println(result);
result = sqrt(-10);
delay(1000);
Serial.println(result);
delay(10000);
}


And the result was the same. So, is there some kind of documentation about error management in AVR since this is important to know while development.



P.S. Everything was run on a real Atmega 328p chip on an arduino nano.







arduino-ide avr mathematics error






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 7 hours ago

























asked 8 hours ago









Coder_fox

32518




32518












  • I think the standard is that it is undefined for integer math. The floating point is according to the IEEE standard and returns a nan, but no exception. Catching an exeption in the Arduino is not possible (I think) : stackoverflow.com/questions/10095591/… When you find strange things with a byte, please give a full sketch that we can try and tell us which arduino board you use.
    – Jot
    8 hours ago












  • @Jot This is an interesting point but why would a nan be replaced with 4294967295. Apparently they don't have the same binary value. Why did Atmel not include a nan value (that maybe could be disabled through fuses) in their processor architecture. This is a useful troubleshooting feature that is heavily used in all major programming languages.
    – Coder_fox
    8 hours ago










  • @Jot I used an Arduino nano with an Atmega 328p on board.
    – Coder_fox
    8 hours ago










  • An integer can not be a 'nan', that is specified for floating point. Please update your question with board and microcontroller, and perhaps a full sketch.
    – Jot
    8 hours ago










  • I tried to make a sketch myself, and I have different results. Please show your sketch and tell us the results of the sketch that you show. Are you running this in a simulator?
    – Jot
    8 hours ago




















  • I think the standard is that it is undefined for integer math. The floating point is according to the IEEE standard and returns a nan, but no exception. Catching an exeption in the Arduino is not possible (I think) : stackoverflow.com/questions/10095591/… When you find strange things with a byte, please give a full sketch that we can try and tell us which arduino board you use.
    – Jot
    8 hours ago












  • @Jot This is an interesting point but why would a nan be replaced with 4294967295. Apparently they don't have the same binary value. Why did Atmel not include a nan value (that maybe could be disabled through fuses) in their processor architecture. This is a useful troubleshooting feature that is heavily used in all major programming languages.
    – Coder_fox
    8 hours ago










  • @Jot I used an Arduino nano with an Atmega 328p on board.
    – Coder_fox
    8 hours ago










  • An integer can not be a 'nan', that is specified for floating point. Please update your question with board and microcontroller, and perhaps a full sketch.
    – Jot
    8 hours ago










  • I tried to make a sketch myself, and I have different results. Please show your sketch and tell us the results of the sketch that you show. Are you running this in a simulator?
    – Jot
    8 hours ago


















I think the standard is that it is undefined for integer math. The floating point is according to the IEEE standard and returns a nan, but no exception. Catching an exeption in the Arduino is not possible (I think) : stackoverflow.com/questions/10095591/… When you find strange things with a byte, please give a full sketch that we can try and tell us which arduino board you use.
– Jot
8 hours ago






I think the standard is that it is undefined for integer math. The floating point is according to the IEEE standard and returns a nan, but no exception. Catching an exeption in the Arduino is not possible (I think) : stackoverflow.com/questions/10095591/… When you find strange things with a byte, please give a full sketch that we can try and tell us which arduino board you use.
– Jot
8 hours ago














@Jot This is an interesting point but why would a nan be replaced with 4294967295. Apparently they don't have the same binary value. Why did Atmel not include a nan value (that maybe could be disabled through fuses) in their processor architecture. This is a useful troubleshooting feature that is heavily used in all major programming languages.
– Coder_fox
8 hours ago




@Jot This is an interesting point but why would a nan be replaced with 4294967295. Apparently they don't have the same binary value. Why did Atmel not include a nan value (that maybe could be disabled through fuses) in their processor architecture. This is a useful troubleshooting feature that is heavily used in all major programming languages.
– Coder_fox
8 hours ago












@Jot I used an Arduino nano with an Atmega 328p on board.
– Coder_fox
8 hours ago




@Jot I used an Arduino nano with an Atmega 328p on board.
– Coder_fox
8 hours ago












An integer can not be a 'nan', that is specified for floating point. Please update your question with board and microcontroller, and perhaps a full sketch.
– Jot
8 hours ago




An integer can not be a 'nan', that is specified for floating point. Please update your question with board and microcontroller, and perhaps a full sketch.
– Jot
8 hours ago












I tried to make a sketch myself, and I have different results. Please show your sketch and tell us the results of the sketch that you show. Are you running this in a simulator?
– Jot
8 hours ago






I tried to make a sketch myself, and I have different results. Please show your sketch and tell us the results of the sketch that you show. Are you running this in a simulator?
– Jot
8 hours ago












1 Answer
1






active

oldest

votes

















up vote
6
down vote



accepted










The simple answer is: they are not handled at all.



According to the C and C++ standards, what you are invoking is called
undefined behavior, meaning anything can happen. In practical
terms, it means that the compiler can do its optimizations assuming
you will never invoke undefined behavior, and completely disregard what
could happen if the assumption does not hold. The generated code could
be completely broken, it won't be the compiler's fault.



The AVR architecture cannot do divisions, nor floating point math. Thus
all the errors you have here happen at the software level. Note that
sqrt(-10) is not an error (it's NaN, which is correctly handled by
the avr-libc), but converting that to an int (which you do when you
assign it to result) is an error.



If you really want to know the details of what happens with each of
these errors, there is only one option: you have to disassemble the
executable program and read the assembly listing.






share|improve this answer





















  • Thanks for the great explanation.
    – Coder_fox
    7 hours ago






  • 2




    "... undefined behavior, meaning anything can happen." - It's worth emphasizing that this is completely a C/C++ thing, unrelated to the AVR chips. The exact same warning applies to code running on, say, an Intel i5.
    – marcelm
    5 hours ago










  • Also worth noting that while the C++ standard states that the compiler can do anything, C++ compilers typically define additional behavior beyond the C++ specification. For example, Visual Studio's compiler defines the behavior of x/0 which was undefined in the C++ spec, based on what it knows about the architecture. This is really useful when you want to do something the spec forbids, but your particular compiler permits, like gcc extensions.
    – Cort Ammon
    3 hours ago











Your Answer






StackExchange.ifUsing("editor", function () {
return StackExchange.using("schematics", function () {
StackExchange.schematics.init();
});
}, "cicuitlab");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "540"
};
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',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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%2farduino.stackexchange.com%2fquestions%2f58301%2fhow-are-errors-not-related-to-syntax-managed-in-arduino-and-in-the-avr-archite%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
6
down vote



accepted










The simple answer is: they are not handled at all.



According to the C and C++ standards, what you are invoking is called
undefined behavior, meaning anything can happen. In practical
terms, it means that the compiler can do its optimizations assuming
you will never invoke undefined behavior, and completely disregard what
could happen if the assumption does not hold. The generated code could
be completely broken, it won't be the compiler's fault.



The AVR architecture cannot do divisions, nor floating point math. Thus
all the errors you have here happen at the software level. Note that
sqrt(-10) is not an error (it's NaN, which is correctly handled by
the avr-libc), but converting that to an int (which you do when you
assign it to result) is an error.



If you really want to know the details of what happens with each of
these errors, there is only one option: you have to disassemble the
executable program and read the assembly listing.






share|improve this answer





















  • Thanks for the great explanation.
    – Coder_fox
    7 hours ago






  • 2




    "... undefined behavior, meaning anything can happen." - It's worth emphasizing that this is completely a C/C++ thing, unrelated to the AVR chips. The exact same warning applies to code running on, say, an Intel i5.
    – marcelm
    5 hours ago










  • Also worth noting that while the C++ standard states that the compiler can do anything, C++ compilers typically define additional behavior beyond the C++ specification. For example, Visual Studio's compiler defines the behavior of x/0 which was undefined in the C++ spec, based on what it knows about the architecture. This is really useful when you want to do something the spec forbids, but your particular compiler permits, like gcc extensions.
    – Cort Ammon
    3 hours ago















up vote
6
down vote



accepted










The simple answer is: they are not handled at all.



According to the C and C++ standards, what you are invoking is called
undefined behavior, meaning anything can happen. In practical
terms, it means that the compiler can do its optimizations assuming
you will never invoke undefined behavior, and completely disregard what
could happen if the assumption does not hold. The generated code could
be completely broken, it won't be the compiler's fault.



The AVR architecture cannot do divisions, nor floating point math. Thus
all the errors you have here happen at the software level. Note that
sqrt(-10) is not an error (it's NaN, which is correctly handled by
the avr-libc), but converting that to an int (which you do when you
assign it to result) is an error.



If you really want to know the details of what happens with each of
these errors, there is only one option: you have to disassemble the
executable program and read the assembly listing.






share|improve this answer





















  • Thanks for the great explanation.
    – Coder_fox
    7 hours ago






  • 2




    "... undefined behavior, meaning anything can happen." - It's worth emphasizing that this is completely a C/C++ thing, unrelated to the AVR chips. The exact same warning applies to code running on, say, an Intel i5.
    – marcelm
    5 hours ago










  • Also worth noting that while the C++ standard states that the compiler can do anything, C++ compilers typically define additional behavior beyond the C++ specification. For example, Visual Studio's compiler defines the behavior of x/0 which was undefined in the C++ spec, based on what it knows about the architecture. This is really useful when you want to do something the spec forbids, but your particular compiler permits, like gcc extensions.
    – Cort Ammon
    3 hours ago













up vote
6
down vote



accepted







up vote
6
down vote



accepted






The simple answer is: they are not handled at all.



According to the C and C++ standards, what you are invoking is called
undefined behavior, meaning anything can happen. In practical
terms, it means that the compiler can do its optimizations assuming
you will never invoke undefined behavior, and completely disregard what
could happen if the assumption does not hold. The generated code could
be completely broken, it won't be the compiler's fault.



The AVR architecture cannot do divisions, nor floating point math. Thus
all the errors you have here happen at the software level. Note that
sqrt(-10) is not an error (it's NaN, which is correctly handled by
the avr-libc), but converting that to an int (which you do when you
assign it to result) is an error.



If you really want to know the details of what happens with each of
these errors, there is only one option: you have to disassemble the
executable program and read the assembly listing.






share|improve this answer












The simple answer is: they are not handled at all.



According to the C and C++ standards, what you are invoking is called
undefined behavior, meaning anything can happen. In practical
terms, it means that the compiler can do its optimizations assuming
you will never invoke undefined behavior, and completely disregard what
could happen if the assumption does not hold. The generated code could
be completely broken, it won't be the compiler's fault.



The AVR architecture cannot do divisions, nor floating point math. Thus
all the errors you have here happen at the software level. Note that
sqrt(-10) is not an error (it's NaN, which is correctly handled by
the avr-libc), but converting that to an int (which you do when you
assign it to result) is an error.



If you really want to know the details of what happens with each of
these errors, there is only one option: you have to disassemble the
executable program and read the assembly listing.







share|improve this answer












share|improve this answer



share|improve this answer










answered 7 hours ago









Edgar Bonet

23.3k22344




23.3k22344












  • Thanks for the great explanation.
    – Coder_fox
    7 hours ago






  • 2




    "... undefined behavior, meaning anything can happen." - It's worth emphasizing that this is completely a C/C++ thing, unrelated to the AVR chips. The exact same warning applies to code running on, say, an Intel i5.
    – marcelm
    5 hours ago










  • Also worth noting that while the C++ standard states that the compiler can do anything, C++ compilers typically define additional behavior beyond the C++ specification. For example, Visual Studio's compiler defines the behavior of x/0 which was undefined in the C++ spec, based on what it knows about the architecture. This is really useful when you want to do something the spec forbids, but your particular compiler permits, like gcc extensions.
    – Cort Ammon
    3 hours ago


















  • Thanks for the great explanation.
    – Coder_fox
    7 hours ago






  • 2




    "... undefined behavior, meaning anything can happen." - It's worth emphasizing that this is completely a C/C++ thing, unrelated to the AVR chips. The exact same warning applies to code running on, say, an Intel i5.
    – marcelm
    5 hours ago










  • Also worth noting that while the C++ standard states that the compiler can do anything, C++ compilers typically define additional behavior beyond the C++ specification. For example, Visual Studio's compiler defines the behavior of x/0 which was undefined in the C++ spec, based on what it knows about the architecture. This is really useful when you want to do something the spec forbids, but your particular compiler permits, like gcc extensions.
    – Cort Ammon
    3 hours ago
















Thanks for the great explanation.
– Coder_fox
7 hours ago




Thanks for the great explanation.
– Coder_fox
7 hours ago




2




2




"... undefined behavior, meaning anything can happen." - It's worth emphasizing that this is completely a C/C++ thing, unrelated to the AVR chips. The exact same warning applies to code running on, say, an Intel i5.
– marcelm
5 hours ago




"... undefined behavior, meaning anything can happen." - It's worth emphasizing that this is completely a C/C++ thing, unrelated to the AVR chips. The exact same warning applies to code running on, say, an Intel i5.
– marcelm
5 hours ago












Also worth noting that while the C++ standard states that the compiler can do anything, C++ compilers typically define additional behavior beyond the C++ specification. For example, Visual Studio's compiler defines the behavior of x/0 which was undefined in the C++ spec, based on what it knows about the architecture. This is really useful when you want to do something the spec forbids, but your particular compiler permits, like gcc extensions.
– Cort Ammon
3 hours ago




Also worth noting that while the C++ standard states that the compiler can do anything, C++ compilers typically define additional behavior beyond the C++ specification. For example, Visual Studio's compiler defines the behavior of x/0 which was undefined in the C++ spec, based on what it knows about the architecture. This is really useful when you want to do something the spec forbids, but your particular compiler permits, like gcc extensions.
– Cort Ammon
3 hours ago


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2farduino.stackexchange.com%2fquestions%2f58301%2fhow-are-errors-not-related-to-syntax-managed-in-arduino-and-in-the-avr-archite%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

サソリ

広島県道265号伴広島線

Accessing regular linux commands in Huawei's Dopra Linux