Какой из этих ответов относительно функций является неправильным?

17

Поэтому, пока я делал несколько длинных компиляций, я решил пройти общий тест C ++ на ODesk и наткнулся на этот вопрос.

Этот вопрос

Если я не ошибаюсь, учитывая формулировку (или ее отсутствие), все это может быть правдой.

а.

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

б. Ну, это return void;было бы неправильно семантически, но функции, очевидно, могут иметь voidвозвращаемые типы.

void Foo() { }

с. Это определение встроенных функций, да.

д. Не вдаваясь в подробности о размещении следующих элементов,

typedef void (*Func)(int);

Func functions[2];

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

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

Кроме того, вы всегда можете сделать это, используя лямбды и функторы .

е.

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

int foobar = 5;
Foo(foobar);

е.

int bar = 5;

int& GetBar()
{
    return bar;
}

GetBar() = 6;

грамм.

int bar = 5;

int* GetBar()
{
    return &bar;
}

(*GetBar()) = 5;

Я не вижу, где на этот вопрос есть какие-то действительно ложные ответы. Я что-то пропустил?

Излишне говорить, что у меня не хватило времени и все провалилось. Думаю, я плохой программист на C ++. :(

Qix
источник
18
Пришел сюда, чтобы орать на какого-то ребенка, вставляющего домашнее задание, был приятно удивлен.
SomeKittens
На самом деле не все языки требуют расширения встроенных функций. «inline» - подсказка компилятора, а не команда в Delphi, и C, C ++ имеют исключения . Так что «с» также может быть ложным. Может быть более интересно написать ответ, показывающий, как каждое утверждение может быть неправильным.
1
@ Ӎσᶎ Если бы только было текстовое поле. Я хочу вернуться и нажать «Сообщить о проблеме с этим вопросом».
Qix
5
Это не массив функций. Это массив указателей на функции.
user253751
@immibis Верно, но вопрос на самом деле не проясняется (по крайней мере, мне это не удалось).
Qix

Ответы:

21

Весь этот вопрос хитрый. Формулировка вопроса подразумевает возможность множественного выбора, в то время как переключатели указывают на один выбор.

Кроме того, b довольно подозрительно, поскольку функции void ничего не возвращают.

D также сомнителен, поскольку, насколько я знаю, у вас не может быть массива функций. Конечно, вы можете иметь массив указателей на функции, но это не одно и то же.

как зовут
источник
Правильно; D все равно что спросить, можете ли вы позвонить int. Конечно, если вы приведете его к указателю, и этот указатель ссылается на функцию ...
Qix
1
Я готов поспорить, что D - это ответ, на который они рассчитывают, но да, вопрос плохой.
Gort the Robot
Хотя voidфункции не возвращают никакого значения , они по-прежнему возвращают тип void . Таким образом, я говорю, что Б правда.
Томас Эдинг
@ThomasEding Это все еще очень плохая формулировка с их стороны. Вы не return void;, но вместо этого return;.
Qix
10

Ответ в) также возможно ложный.

«Встроенные функции расширяются во время компиляции, чтобы избежать накладных расходов при их вызове».

Во-первых, компилятору C ++ разрешено игнорировать inlineподсказку, вообще не расширяя функции.

Во-вторых, заявленная «причина» расширения - это упрощение. Фактически, настоящая причина для расширения (или нет) полностью находится в руках автора компилятора.

Стивен С
источник
Вы правы, но я думал об этом в смысле «хорошо, компилятор определил, что он хочет встроить функцию», а не inlineподсказку.
Qix
Ну, компилятор не может полностью игнорировать подсказку. По крайней мере, это обязательный эффект, исключение из ODR.
Дедупликатор
@ Дедупликатор - да, может. «Независимо от того, как вы определяете функцию как встроенную, это запрос, который компилятор может игнорировать: компилятор может встроить-развернуть некоторые, все или ни одного из мест, где вы вызываете функцию, обозначенную как встроенную». - источник isocpp.org/wiki/faq/Inline-Functions
Стивен С.
@StephenC: запрос на расширение его в строке может быть проигнорирован, да. Я только сказал, что явного исключения из ODR не может.
Дедупликатор
Понимаю. Я обновил формулировку своего ответа
Стивен С
7

с. Это определение встроенных функций, да.

Это не совсем верно.
Несмотря на название, ключевое слово inlineне гарантирует, что функция будет встроенной. Единственное, в чем вы можете быть уверены, это то, что компилятор не будет жаловаться, если несколько раз увидит определение встроенной функции.

Так что, строго говоря, вариант C неверен, но я не думаю, что это ответ, которого ожидают авторы теста, потому что есть ответ, который еще более неправильный.

д. Не вдаваясь в подробности о размещении следующих элементов,

typedef void (*Func)(int);

Func functions[2];

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

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

Кроме того, вы всегда можете сделать это, используя лямбды и функторы.

В вашем примере functionsэто массив указателей на функции, а не массив самих функций. Точно так же лямбды и функторы на самом деле не являются функциями. Это классы, которые отвечают на оператор вызова функции, но это не делает их функциями в глазах определения языка C ++.

Функции в C ++ немного похожи на граждан второго сорта. Вы можете определить и вызвать их, но как только вы попытаетесь сделать что-то еще с типом функции (например, создать их массив), вы либо получите ошибку, либо они молча преобразуют себя в указатель.

Барт ван Инген Шенау
источник
Я согласен с битом D, но я читал cкак функции, которые уже были положительно помечены для встраивания, по сравнению с inlineсамим ключевым словом. Я понимаю inline, это намек.
Qix
4

Во всяком случае, это должно быть б . Вы не можете , но вы можете вернуть . Пустота в объявлении функции должна быть там, чтобы уведомить компилятор об отсутствии возвращаемого значения.returnvoidnull

Тип пустоты

В C и C ++

Функция с типом результата void завершается либо достижением конца функции, либо выполнением оператора возврата без возвращаемого значения. Тип void также может появляться как единственный аргумент прототипа функции, чтобы указать, что функция не принимает аргументов. Обратите внимание, что, несмотря на название, во всех этих ситуациях тип void служит типом единицы, а не нулевым или нижним типом, хотя в отличие от типа реальной единицы, который является одиночным, тип void, как говорят, содержит пустой набор значений, и язык не предоставляет никакого способа объявить объект или представить значение с типом void.

Адам Цукерман
источник
2
-1: хотя voidфункции не возвращают никакого значения , они по-прежнему возвращают тип void . Таким образом, я говорю, что Б правда.
Томас Эдинг
Возвращение недействительным допускается при некоторых обстоятельствах. Смотрите здесь .
Джош Келли