...

воскресенье, 4 июня 2017 г.

[Из песочницы] Когда 2 + 2 = «4»

Во время отдыха от отладки 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("%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

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

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

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

Комментарии (0)

    Let's block ads! (Why?)

    Комментариев нет:

    Отправить комментарий