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

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

C/C++

  • В языке C можно индексировать массивы следующим образом:
a[10]

И это очень распространённый способ.
Однако существует и другая, менее известная реализация:

10[a]

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

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


  • Триграф в C и C++:
int main() {
   printf("LOL??!");
}

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

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


  • В языке 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);
    }
}

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


  • Для каких странностей могут использоваться шаблоны в 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

  • В Java следующий код:
int[] numbers() {
  return null;
}

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

int numbers() [] {
  return null;
}

  • Странное поведение при упаковке целых значений в 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

  • Как PHP обрабатывает числовые значения в строках:
"01a4" != "001a4"

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

"01e4" == "001e4"

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

JavaScript

  • Странности при сложении и вычитании в JavaScript:
 '5' + 3 // ='53'

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

'5' - 3 // =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

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

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

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

Основано на Stack Overflow

Подобрали три теста для вас:
— А здесь можно применить блокчейн?
Серверы для котиков: выберите лучшее решение для проекта и проверьте себя.
Сложный тест по C# — проверьте свои знания.

Также рекомендуем: