It returns a const int, but is not considered a constant expression. In C, which doesn't support dynamic initialization, it would be illegal to initialize a global variable like that, or to use that function to declare an array, etc.
C++ supports dynamic initialization, but it still follows the same constant expression rules. Try saying, for example:
Code:
template <int Size>
class Test
{
/* ... */
};
Test <add_numbers (3, 1)> obj; // Illegal. Template param is not a const expr.
int Four_Integers [add_numbers (3, 1)]; /* EDIT: Yes, this is a variable length array,
because it's not declared with a const expr. */