Возвращать логическое значение в функции без определенного возвращаемого типа и сохранять результат в компиляции char без ошибок - почему? - PullRequest
0 голосов
/ 11 июля 2020

Рассмотрим эту программу:

#include <iostream>

printStatement(std::string msg) {
    std::cout << msg;
    return true;
}

int main() {
    char w = printStatement("Hello World");
}

Я использую MinGW g cc для компиляции этого кода на Windows, и, к моему удивлению, компилятор компилирует это без каких-либо возражений, переменная w, очевидно, равна устанавливается в '\ 001' после вызова функции. Меня беспокоит несколько вещей:

  1. printStatement не имеет возвращаемого типа - очевидно, для него неявно установлено значение «int»?
  2. Но я возвращаю логическое значение - есть ли неявное преобразование в int происходит?
  3. Я сохраняю результат в char - происходит ли снова неявное преобразование из int в char?

Я действительно сомневаюсь: кто меня останавливает от стрельбы в колени при разработке C ++, потому что компилятору явно все равно.

Ответы [ 3 ]

3 голосов
/ 11 июля 2020
  1. printStatement не имеет возвращаемого типа - очевидно, для него неявно установлено значение «int»?

Не в стандартном C ++. Такое заявление неверно сформировано. Но раньше так было в первом C стандарте (около 30 лет go) и в предварительном C (даже старше). Некоторые компиляторы поддерживают это как расширение языка для обратной совместимости.

Но я возвращаю логическое значение - происходит ли неявное преобразование в int?

Да. bool неявно преобразуется в целочисленные типы.

Я сохраняю результат в char - происходит ли снова неявное преобразование из int в char?

Да. Целочисленные типы можно преобразовать в char.

Кто мешает мне стрелять в колени при разработке C ++, потому что, очевидно, компилятору все равно.

Ваш работодатель / ведущий разработчик может потребовать, чтобы вы не использовали языковые расширения, потому что это проблема с точки зрения переносимости.

Компилятор требуется для диагностики неправильно сформированного объявления. Вот пример сообщения Diagnosti c, которое может быть выдано:

ISO C ++ запрещает объявление 'printStatement' без типа [-fpermissive]

Чтение вывод компилятора важен для предотвращения ошибок программиста на C ++. Если компилятор не выдает такого сообщения диагностики c, значит, он не соответствует стандарту C ++. Обычно это считается ошибкой в ​​компиляторе.

PS Преобразование из int в char может быть потенциально опасным (в большинстве систем), потому что значение может не быть представлено в целевом типе. В вашем компиляторе есть возможность предупреждать о таких потенциально опасных преобразованиях (-Wconversion).

3 голосов
/ 11 июля 2020

Неявные возвращаемые типы запрещены всеми стандартами C ++. Некоторые реализации могут позволить им существовать. Это запрещено большинством отраслевых стандартов кодирования. Я даже не собираюсь смотреть, как g cc справляется с этой ситуацией (подразумевает ли он возвращаемое значение int или bool), поскольку вам действительно не следует этого делать.

Это поведение, определяемое реализацией, но вы не должны этого делать. Включите все предупреждения -Wall, и этого следует предупреждать. В любом случае вы должны включить -Wall по умолчанию и рассматривать все предупреждения как ошибки, если только у вас нет ОЧЕНЬ веской причины для включения кода предупреждения.

Я понимаю, что не отвечаю на ваши пронумерованные вопросы, но настоящий ответ на ваши вопросы: «Все это не имеет значения, не делайте этого, включите предупреждения».

Источник: https://wiki.sei.cmu.edu/confluence/display/c/DCL31-C.+Declare+identifiers+before+using+them

2 голосов
/ 11 июля 2020

printStatement не имеет возвращаемого типа - по-видимому, это неявно установлено в "int"?

это незаконно в C ++

Но я возвращаюсь логическое значение - происходит ли неявное преобразование в int?

Я сохраняю результат в char - происходит ли снова неявное преобразование из int в char?

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

Если вы не хотите объявлять возвращаемый тип, позволяя компилятору делать / решать за вас, используйте auto:

#include <iostream>

auto printStatement(std::string msg) {
    std::cout << msg;
    return true;
}

int main() {
    char w = printStatement("Hello World");
}

и

pi@raspberrypi:/tmp $ g++ -Wall c.cc
c.cc: In function ‘int main()’:
c.cc:9:10: warning: unused variable ‘w’ [-Wunused-variable]
     char w = printStatement("Hello World");
          ^
pi@raspberrypi:/tmp $ 

Добавление, например return w; в конце main :

pi@raspberrypi:/tmp $ g++ -Wall c.cc
pi@raspberrypi:/tmp $ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...