Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is omitting return statement undefined behaviour in C89 (aka ANSI C)?

Consider following basic example:

#include <stdio.h>

int main(void)
{
    printf("Hi there!\n");
}

Does it invoke undefined behaviour in C89? I tried to get some sense from this question, but most upvoted answers claim that it's implementation-defined and definitely no UB here (with comments of Keith Thompson, that looks contradictory).

The spec says in §3.16 Definitions and conventions:

If a “shall” or “shall not” requirement that appears outside of a constraint is violated. the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words “undefined behavior” or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three: they all describe “behavior that is undefined”.

and §5.1.2.2.3 Program termination:

A return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument. If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined.

My understanding is that latter subclause does not cover case of missing return, as return statement in not never invoked, thus former subclause applies.

However futher reading indicates something different, §6.6.6.4 The return statement:

If a return statement without an expression is executed, and the value of the function call is used by the caller, the behavior is undefined. Reaching the } that terminates a function is equivalent to executing a return statement without an expression.

Ok, so now 5.1.2.2.3 subclause applies:

If the main function executes a return that specifies no value. the termination status returned to the host environment is undefined.

The term "termination status is undefined" does not seem to be UB, nor any specific behavior, but more like it's outside of scope of C Standard, thinking more like: "let the host environment to be worry about, we wash our hands from here". Is it correct intepretation?

like image 982
Grzegorz Szpetkowski Avatar asked Jan 28 '15 22:01

Grzegorz Szpetkowski


People also ask

Do you need return statement in C?

In a main function, the return statement and expression are optional.

What does empty return mean in C?

A return statement without an expression shall only appear in a function whose return type is void.

Can a function be defined without a return statement?

Believe it or not, a function typed something other than void is not required to have a return statement. It's not enforced by the language grammar, and there is no constraint that a non- void function must contain a return statement.


2 Answers

Years ago I actually debugged issues caused by this. It gets even more interesting if you have some code paths with returns and others without.

As @aruisdante surmised in the comments, the behavior exhibited is indeed 'undefined', but the only undefined part is the value returned (it's not like many other 'undefined' situations that may crash the program).

These days this actually amounts to a security risk because the 'undefined' value returned is generally whatever happens to be in the CPU register normally used to return values (or on the stack in some implementations), which could theoretically be used to leak sensitive data.

like image 112
James Avatar answered Oct 04 '22 06:10

James


I believe that intent of Standard Committee was that this termination status value is unspecified.

According to N739 draft:

and change the last sentence of subclause 5.1.2.2.3 from:

If the /main/ function executes a return that specifies no value, the termination status returned to the host environment is undefined.

to:

If the /main/ function executes a return that specifies no value, | the termination status returned to the host environment is unspecified.

[The concept of undefined value is carefully avoided elsewhere.]

You may also find in further Standards, that terminology was changed and term "unspecified" is used consequently.

I would say that it's definitely not intented to be undefined behaviour per se, but still it's impossible to decide whether it's unspecified behavior or as I said no behaviour at all. Other excerpt, that would indicate latter these is §1 Scope:

This International Standard does not specify:

  • the mechanism by which C programs are invoked for use by a data-processing system;

I would expect this also means that this International Standard does not specify how programs's termination status is handled by host environment.

like image 24
Grzegorz Szpetkowski Avatar answered Oct 04 '22 04:10

Grzegorz Szpetkowski