Во время отдыха от отладки JavaScript, я читал статью про особенности PHP и неожиданно задумался каковы же будут результаты сравнения 2 + 2 = «4» для разных языков программирования. И вот что из этого получилось.
Итоговая таблица для тех кто не хочет много читать | |||
Результат | Ошибка компиляции | False | True |
Языки | C++ Pascal FORTRAN-95 Java C# Go Rust Haskel |
C Lisp Python Lua Ruby |
JavaScript PHP Perl |
Компилятор C выдаёт предупреждение, компилятор C++ ошибку которая превращается в предупреждение если указать флаг -fpermissive.
Под катом для каждого из языков приведена строчка кода, вызвавшая тот или иной результат, с небольшим комментарием.
Бонусом — функции вывода на консоль для этих языков.
Ошибка компиляции
Самый простое и неинтересное поведение — это ошибка компиляции, происходит во всех строго типизированных языках.
C++
cout << (2 + 2 == "4") << endl;
error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
Если указать флаг -fpermissive то произойдёт сравнение указателя на строку и числа 4 которое скорее всего вернёт 0.
Pascal
writeln((2 + 2) = "4");
Fatal: illegal character "'"'" ($22)
Сообщение об ошибке довольно непонятное
FORTRAN-95
Print *, 2 + 2 == "4"
Error: Operands of comparison operator '==' at (1) are INTEGER(4)/CHARACTER(1)
Забавно что в этом тексте нет собственно сообщения о том, что сравнение невозможно, просто констатация факта.
Java
System.out.println((2 + 2) == "4");
error: incomparable types: int and String
В сообщение об ошибке всё хорошо кроме того, что не указана какая операция вызвала ошибку.
C#
Console.WriteLine((2 + 2) == "4");
error CS0019: Operator `==' cannot be applied to operands of type `int' and `string'
Тут всё хорошо.
Go
fmt.Printf(2 + 2 == "4")
cannot convert «4» to type int
invalid operation: «4» == 2 + 2 (mismatched types string and int)
А тут еще лучше
Rust
println!("{:?}", 2 + 2 == "4");
error: the trait `core::cmp::PartialEq<&str>` is not implemented for the type `_` [E0277]
Логичное, но честно говоря далеко не самое понятное сообщение об ошибке
Haskel
main = putStrLn (show ((2 + 2) == "4"))
No instance for (Num Char) arising from a use of `+'
Сперва я не понял сообщение, потом немного подумал и понял. Но стал понимать Haskel еще меньше чем раньше.
Результат False
Следующие на очереди языки которые позволяют сравнивать число и строку, при этом возвращая false (или что-то похожее), скорее всего из-за несовпадения типов переменных.
C
printf("%in",(2 + 2 == "4"));
результат — 0. Сравнение указателя на строку и числа 4 скорее всего вернёт 0. При этом выводится предупреждение, почти такое же как в C++:
warning: comparison between pointer and integer [enabled by default]
Lisp
(write (eq "123" 123))
результат — NIL
Python
print (2 + 2 == "4")
результат — False
Lua
print(2 + 2 == "4")
результат — false
Ruby
puts 2 + 2 == "4";
результат — false
Результат True
И наконец языки которые вернут true для сравнения.
JavaScript
console.log(2 + 2 == "4");
К счастью есть операция строгого сравнения (тройное равенство ===), которая вернёт false
PHP
echo (2 + 2 == "4");
Так же, как и в JavaScript есть операция тройное равенство, результатом которой будет FALSE, что при выводе на консоль выглядит как пустая строка (если я что-то путаю поправьте меня).те меня).
Perl
print 2 + 2 == "4";
Операции строгого сравнения нет, кроме того для шестнадцатеричной записи (а почему бы и нет)
print 0x2 + 0x2 == "0x4";
Perl интерпретирует строку «0x4» как 0 (в отличие от JavaScript и PHP, которые разбирают шестнадцатеричные строки) и вернёт FALSE, при выводе на консоль так же будет пустая строка.
Есть ли еще языки с необычным поведением при сравнении числа со строкой, я пока не знаю.
Для изучения вопроса использовался сайт, используемые версии компиляторов и интерпретаторов соответствуют предоставленным на сайте.
Автор: igormich88