function return value problem on STM32

I'm just getting started on an STM32 board after a couple of years on AVR boards. The following program runs fine on the AVR, (prints a whole series of "101" as expected) but on the STM32, it's wonky - a series of numbers less than 100 are printed, and after a short time the program freezes. I know what's wrong with the program - the function doNext() has declared a return value but not defined one; if I change the function type to void, or return an integer value, the problem goes away. I've never seen a C++ system before where that sort of omission causes the code to execute improperly. I'm guessing it has something to do with how the STM32 manages its stack. Can someone give me some insight into what's going on? Thanks!

void setup() {
  Serial.begin(9600);
  delay(2000);
}

void loop() {
  doNext();
}
              
int lastValueUsed = 0;
int doNext() {
  int currValue = random(102);
  int diff = abs(lastValueUsed - currValue);
  if (diff > 100) {
    Serial.println(diff);
    lastValueUsed = currValue;
  }
}

WHY on earth do you define a function to return and int, then NOT return an int? What is the point?

Patient: Doctor, it hurts when I do this.
Doctor: Then don't DO that!

It was an ERROR! But I want to use it as an opportunity to understand the processor's software architecture a bit better.

There is clearly a compiler or runtime bug - which board exactly? which toolset?

STM32H7 running in the Arduino IDE, using STM32CubeProgrammer. This is a Daisy Seed board, which I'm just getting started with (brand-new to STM32 boards!)

MarkT:
There is clearly a compiler or runtime bug - which board exactly? which toolset?

Not necessarily a compiler bug:
https://en.cppreference.com/w/cpp/language/return#notes

Flowing off the end of a value-returning function (except main) without a return statement is undefined behavior.

https://en.cppreference.com/w/cpp/language/ub

  • undefined behavior - there are no restrictions on the behavior of the program. Examples of undefined behavior are memory accesses outside of array bounds, signed integer overflow, null pointer dereference, more than one modifications of the same scalar in an expression without any intermediate sequence point (until C++11)that are unsequenced (since C++11), access to an object through a pointer of a different type, etc. Compilers are not required to diagnose undefined behavior (although many simple situations are diagnosed), and the compiled program is not required to do anything meaningful.

If the compiler didn't warn you about this, turn up your warning level in the settings before doing anything else.

Pieter

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.