Pull to refresh

Когда 2 + 2 = «4»

Reading time3 min
Views20K
Во время отдыха от отладки 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)
Сообщение об ошибке довольно непонятное

writeln(2 + 2 = '4');

Error: Incompatible types: got «Char» expected «Int64»
Сообщение об ошибке стало вполне понятным. Спасибо GebekovAS.

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 еще меньше чем раньше.
Решение от Sirikid если всё таки очень хочется сравнить ideone.com/CJifV3

Результат False


Следующие на очереди языки которые позволяют сравнивать число и строку, при этом возвращая false (или что-то похожее), скорее всего из-за несовпадения типов переменных.

C

printf("%i\n",(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


2+2=«4»

False
Спасибо, ACPrikh. «Адинэснеги встали в ряд гуру C Lisp Python Lua Ruby.»

Результат 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, при выводе на консоль так же будет пустая строка.

REXX
say 2+2="4"

true
Спасибо, impetus. «При дефолтных ключах/настройках, что документировано и для этого языка логично и ожидаемо.»

Tcl
puts [expr { 2 + 2 == "4" }]

true
Спасибо Chpock, «every value is a string».

Есть ли еще языки с необычным поведением при сравнении числа со строкой, я пока не знаю.

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

UPDATE
Исправил досадную ошибку с паскалем, спасибо указавшим. И добавил примеры из комментариев.
Tags:
Hubs:
Total votes 63: ↑37 and ↓26+11
Comments84

Articles