Обновление функции внутри функции

Я наткнулся на странный С++-фрагмент. Я считаю это неправильным кодом. Почему кто-то повторяет объявление функции внутри функции? Он даже компилируется при смене сигнатуры типа на unsigned int sum(int, int), производя ожидаемый результат 4294967294j. Почему это даже компилируется?

#include <iostream>
#include <typeinfo>

using namespace std;

int sum(int a, int b){
    return a + b;
}

int main()
{
    int sum(int, int); // redeclaring sum???
    int a = -1;
    auto result = sum(a, a);
    cout << result << typeid(result).name() << endl;
}

Изменить: он компилируется для меня... но действительно ли это код на С++? Если нет, то почему компилятор (mingw 4.8.1) разрешает это?

Ответ 1

Иногда возникает смысл переопределить функцию внутри области блока. Например, если вы хотите установить аргумент по умолчанию. Рассмотрим следующий код

#include <typeinfo>

using namespace std;

int sum(int a, int b){
    return a + b;
}

int main()
{
    int sum(int, int = -1 ); // redeclaring sum???
    int a = -1;
    auto result = sum(a, a);
    cout << result << typeid(result).name() << endl;

    result = sum(a);
    cout << result << typeid(result).name() << endl;
}

Другой случай - это когда вы хотите вызвать конкретную функцию из набора перегруженных функций. Рассмотрим следующий пример

#include <iostream>

void g( int ) { std::cout << "g( int )" << std::endl; }
void g( short ) { std::cout << "g( short )" << std::endl; }

int main()
{
   char c = 'c';
   g( c );

   {
      void g( short );
      g( c );
   }
}

Ответ 2

Если это действительный код, нет причин для этого.

Если функция sum определена где-то еще, объявление внутри main делает ее доступной только внутри main. Вы не можете использовать его нигде в этой единицы перевода (если, конечно, вы не заявите об этом). Так что это своего рода предельная видимость того, где это необходимо, но, предоставлено, не очень читаемо.

Относительно изменения типа возврата - это незаконно. Вы не видите никаких проблем с unsigned int, но если вы попробуете

char sum(int, int); // redeclaring sum???

вы увидите там проблему.