Не баг, а фича: странное поведение языков программирования

1
774
views

Странное поведение языков программирования

Иногда язык программирования ведёт себя не так, как этого ожидает программист. Сайт tproger.ru опубликовал перевод подборки забавных фич разных языков.

C/C++

1. В языке C можно индексировать массивы следующим образом:

a[10]

И это очень распространённый способ.

Однако существует и другая, менее известная реализация:

10[a]

Код означает то же самое, что и пример выше.

Примечание переводчика: Такой эффект возникает из-за того, что в языке C операция обращения по индексу a[b] — это синтаксический сахар для *(a + b), что, конечно, эквивалентно *(b + a) и в свою очередь b[a].

2. Триграф в C и C++:

int main() {
   printf("LOL??!");
}

На экран будет выведено LOL| без ??!, так как эти три знака формируют триграф |.

Примечание переводчика: Триграфы были удалены в C++17.

3. В языке C метки case оператора switch могут находиться внутри вложенных блоков кода. Ниже приведён пример функции memcpy с использованием этого метода.

void duff_memcpy( char* to, char* from, size_t count ) {
    size_t n = (count+7)/8;
    switch( count%8 ) {
    case 0: do{ *to++ = *from++;
    case 7:     *to++ = *from++;
    case 6:     *to++ = *from++;
    case 5:     *to++ = *from++;
    case 4:     *to++ = *from++;
    case 3:     *to++ = *from++;
    case 2:     *to++ = *from++;
    case 1:     *to++ = *from++;
            }while(--n>0);
    }
}

Примечание переводчика: Этот приём известен как «устройство Даффа».

4.  Для каких странностей могут использоваться шаблоны в C++?

Лучше всего это продемонстрировано в «Многомерных аналоговых Литералах», которые используют шаблоны для вычисления площади нарисованных символами форм. Код ниже действителен для прямоугольника ниже.

#include"analogliterals.hpp"
using namespace analog_literals::symbols;

          unsigned int c = ( o-----o
                             |     !
                             !     !
                             !     !
                             o-----o ).area;

Другой пример с кубом:

assert( ( o-------------o
            |L             \
            | L             \
            |  L             \
            |   o-------------o
            |   !             !
            !   !             !
            o   |             !
             L  |             !
              L |             !
               L|             !
                o-------------o ).volume == ( o-------------o
                                              |             !
                                              !             !
                                              !             !
                                              o-------------o ).area * int(I-------------I) );

Java

1. В Java следующий код:

int[] numbers() {
  return null;
}

Может быть записан таким образом:

int numbers() [] {
  return null;
}

2. Странное поведение при упаковке целых значений в Java:

public class Scratch
{
    public static void main(String[] args)
    {
        Integer a = 1000, b = 1000;
        System.out.println(a == b);

        Integer c = 100, d = 100;
        System.out.println(c == d);
    }
}

После запуска кода в первом случае будет выведено false, а во втором — true.

Примечание переводчика: Объяснение этой особенности языка хорошо описано на Stack Overflow.

PHP

1. Как PHP обрабатывает числовые значения в строках:

"01a4" != "001a4"

Язык PHP не любит строки. Он ищет оправдания для того, чтобы рассматривать введённые в строки значения в виде чисел. Измените немного шестнадцатеричные символы, и PHP внезапно решит, что они уже не относятся к строкам — они становятся числами в научном понимании (PHP не важно, что вы использовали кавычки). Значения выше эквивалентны, так как нули перед другими цифрами игнорируются. Чтобы подкрепить это утверждение, давайте глянем на другой пример:

"01e4" == "001e4"

Для PHP эти значения равны, и это задокументированное явление.

JavaScript

1. Странности при сложении и вычитании в JavaScript:

'5' + 3 // ='53'

Но при этом операция ниже выполняется согласно ожиданиям:

'5' - 3 // =2

2. Таблица «истины» в JavaScript:

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

3. И ещё немного JS напоследок:

JavaScript

Примечание переводчика: Ещё у нас есть интересная статья о скрытых шутках и возможностях в Python.

А для вас что было самым странным и необычным в языках программирования, с которыми вы работаете?



1 КОММЕНТАРИЙ

  1. Вы не написали самое элементарное про PHP, то как он сравнивает числа и строки и обратное!! Но про JS рассписали.

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here