Qual dessas respostas sobre funções está incorreta?

17

Então, enquanto eu faço algumas compilações longas, decidi fazer o teste geral do C ++ no ODesk e me deparei com essa pergunta.

Essa questão

Se não me engano, dada a redação (ou a falta dela), tudo isso pode ser verdade.

uma.

int Foo() { }
int Foo(int bar) { }

b. Bem, return void;seria incorretamente semanticamente, mas as funções podem obviamente ter voidtipos de retorno.

void Foo() { }

c. Esta é a definição de funções embutidas, sim.

d. Sem entrar em muitos detalhes sobre o posicionamento dos seguintes elementos,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Além disso, você sempre pode fazer isso usando lambdas e functors .

e

void Foo(int& bar)
{
    ++bar;
}

int foobar = 5;
Foo(foobar);

f.

int bar = 5;

int& GetBar()
{
    return bar;
}

GetBar() = 6;

g.

int bar = 5;

int* GetBar()
{
    return &bar;
}

(*GetBar()) = 5;

Não vejo onde esta pergunta tem respostas realmente falsas . Estou esquecendo de algo?

Escusado será dizer que fiquei sem tempo e falhei na coisa toda. Eu acho que sou um mau programador de C ++. :(

Qix
fonte
18
Vim aqui para gritar com algum garoto colando lição de casa, fiquei agradavelmente surpreendido.
SomeKittens
Na verdade, nem todos os idiomas exigem que as funções embutidas sejam expandidas. "inline" é uma dica do compilador, e não um comando no Delphi, e C, C ++ têm exceções . Portanto, "c" também pode ser falso. Pode ser mais divertido escrever uma resposta mostrando como cada afirmação pode estar errada.
Móż 18/04/19
1
@ Ӎσᶎ Se ao menos houvesse uma caixa de texto. Quero voltar e clicar em "Informar um problema com esta pergunta".
Qix
5
Isso não é uma matriz de funções. Essa é uma matriz de ponteiros de função.
usar o seguinte comando
@immibis É verdade, mas a pergunta realmente não esclarece (pelo menos para mim não).
Qix

Respostas:

21

Essa questão toda é desonesta. A declaração da pergunta implica a possibilidade de várias opções, enquanto os botões de opção indicam uma única opção.

Além disso, b é bastante suspeito, pois as funções void não retornam nada.

D também é questionável, pois, tanto quanto eu sei, você não pode ter uma matriz de funções. Claro, você pode ter uma variedade de indicadores de função, mas isso não é exatamente a mesma coisa.

whatsisname
fonte
Certo; D é como perguntar se você pode chamar um int. Claro, se você lançá-lo para um ponteiro e que ponteiro se refere a uma função ...
Qix
1
Estou disposto a apostar que D é a resposta que eles estão buscando, mas sim, a pergunta é ruim.
Gort the Robot
Embora as voidfunções não retornem nenhum valor , elas ainda retornam o tipo void . Assim, eu digo que B é verdadeiro.
22614 Thomas Eding
@ThomasEding Isso ainda é uma redação muito ruim da parte deles. Você não return void;, mas sim return;.
Qix
10

A resposta c) também é indiscutivelmente falsa.

"As funções embutidas são expandidas durante o tempo de compilação para evitar sobrecarga de chamada."

Em primeiro lugar, o compilador C ++ tem permissão para ignorar a inlinedica, não expandindo as funções.

Em segundo lugar, a "razão" declarada para fazer a expansão é uma simplificação excessiva. De fato, a verdadeira razão para fazer a expansão (ou não) está inteiramente nas mãos do escritor do compilador.

Stephen C
fonte
Você está correto, mas eu estava pensando sobre isso no sentido de 'ok, o compilador tenha determinado que não quer uma função inline' em vez da inlinedica.
Qix
Bem, o compilador não pode ignorar completamente a dica. Pelo menos é um efeito obrigatório, abrindo uma exceção ao ODR.
Deduplicator
@Duplicador - Sim, pode. "Não importa como você designe uma função como inline, é uma solicitação que o compilador pode ignorar: o compilador pode expandir inline - expandindo alguns, todos ou nenhum dos lugares onde você chama uma função designada como inline". - source isocpp.org/wiki/faq/Inline-Functions
Stephen C
@StephenC: A solicitação para expandi-lo em linha pode ser ignorada, sim. Eu apenas disse que a exceção explícita ao ODR não pode.
Deduplicator
Entendo. Eu atualizei a redação da minha resposta
Stephen C
7

c. Esta é a definição de funções embutidas, sim.

Isso não está completamente certo.
Apesar do nome, a palavra-chave inlinenão garante que uma função seja incorporada. A única coisa que você pode ter certeza é que o compilador não irá reclamar se vir a definição de uma função embutida várias vezes.

Portanto, estritamente falando, a opção C está incorreta, mas não acho que seja a resposta que os autores do questionário esperam, porque há uma resposta ainda mais errada.

d. Sem entrar em muitos detalhes sobre o posicionamento dos seguintes elementos,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Além disso, você sempre pode fazer isso usando lambdas e functors.

No seu exemplo, functionshá uma matriz de ponteiros para funções e não uma matriz de funções em si. Da mesma forma, lambdas e functors também não são realmente funções. São classes que respondem ao operador de chamada de função, mas que não as fazem funcionar aos olhos da definição de linguagem C ++.

As funções em C ++ são um pouco como os cidadãos de segunda classe. Você pode defini-los e chamá-los, mas assim que tentar fazer outra coisa com um tipo de função (como criar uma matriz deles), você receberá um erro ou eles se converterão silenciosamente em um ponteiro.

Bart van Ingen Schenau
fonte
Concordo com o bit D, mas estava lendo ccomo funções que já foram marcadas positivamente para inlining, versus a inlineprópria palavra-chave. Eu entendo inlineé uma dica.
Qix
4

Se alguma coisa, teria que ser b . Você não pode returnum void, mas você pode retornar um null. O nulo na declaração da função deve estar presente para notificar o compilador da falta de um valor retornado.

Tipo de Vazio

Em C e C ++

Uma função com o tipo de resultado nulo termina atingindo o final da função ou executando uma instrução de retorno sem valor retornado. O tipo nulo também pode aparecer como o único argumento de um protótipo de função para indicar que a função não aceita argumentos. Observe que, apesar do nome, em todas essas situações, o tipo de nulo serve como um tipo de unidade, não como um tipo zero ou inferior, mesmo que, diferentemente de um tipo de unidade real que seja um singleton, o tipo de nulo compreenda um vazio conjunto de valores e o idioma não fornece nenhuma maneira de declarar um objeto ou representar um valor com o tipo void.

Adam Zuckerman
fonte
2
-1: Embora as voidfunções não retornem nenhum valor , elas ainda retornam o tipo void . Assim, eu digo que B é verdadeiro.
22614 Thomas Eding
O retorno nulo é permitido sob algumas circunstâncias. Veja aqui .
Josh Kelley