Matriz C de comprimento zero vincula-se ao tipo de ponteiro

Recentemente, escrevi um modelo de função que faz referência a uma matriz C:

template <class T, size_t N>
void foo(T(&c_array)[N]);

Assumindo que T é umchar, o comprimento da corda C éN - 1 devido ao terminador nulo. Percebi que provavelmente deveria lidar com o caso em queN == 0porque entãoN - 1 seriastd::numeric_limits<std::size_t>::max().

Portanto, para evitar o caos que pode ocorrer no raro caso de alguém passar um array de tamanho zero para essa função, eu verifiqueiN == 0.

No entanto, para minha surpresa, parece que uma matriz de comprimento zero não é realmente nem um tipo de matriz - ou pelo menos é nisso que o GCC parece acreditar. De fato, uma matriz de comprimento zero nem sequerligar para a assinatura da função acima, se uma função com uma assinatura do tipo ponteiro estiver disponível como candidato.

Considere o seguinte código:

template <class T, size_t N>
void foo(T(&array)[N])
{
    std::cout << "Array" << std::endl;
}

void foo(const void* p)
{
    std::cout << "Pointer" << std::endl;
}

int main(int argc, char** argv)
{
    char array1[10] = { };
    const char* pointer = 0;
    char array2[0] = { };

    foo(array1);
    foo(pointer);
    foo(array2);
}

Com o GCC 4.3.2, isso gera:

Array
Pointer
Pointer

Estranhamente, a matriz de comprimento zero prefere vincular à função que leva umtipo de ponteiro. Portanto, isso é um bug no GCC ou há algum motivo obscuro exigido pelo padrão C ++ por que esse comportamento é necessário?

questionAnswers(6)

yourAnswerToTheQuestion