Мне пришлось переписать код с одного языка на другой, и я обнаружил, что при доступе к несуществующему индексу массива разные языки ведут себя по-разному.
Подробности под катом.
Вот пример кода на языке структурированного текста, который используется для программирования промышленных контроллеров.
Программы на этом языке могут выполнять различные действия: от управления светофором до наблюдения за процессами на атомной электростанции.
Учтена специфика языка и платформы, поэтому код может выглядеть довольно необычно.
Что делает эта программа? Считывает данные из входных сигналов и записывает управляющее действие в переменную OUT. Значение этой переменной будет 15. Теперь внесем в программу некоторую ошибку, а именно возьмем элемент по несуществующему индексу в массиве и посмотрим на результат.VAR i: INT; OUT: INT; IN: ARRAY [0.4] of INT:= 1, 2, 3, 4, 5; END_VAR OUT := 0; FOR i:= 0 TO 4 DO OUT := OUT + IN[i]; END_FOR;
VAR
i: INT;
OUT: INT;
IN: ARRAY [0.4] of INT:= 1, 2, 3, 4, 5;
END_VAR
OUT := 0;
FOR i:= -1 TO 4 DO
OUT := OUT + IN[i];
END_FOR;
Значение в переменной OUT = 15То есть то же самое, что и до ошибки.
Программа не выдала исключение, а просто проигнорировала несуществующий элемент. Такое поведение для нас вполне приемлемо, если мы случайно не обработали исключение и управляем аварийными стержнями ядерного реактора.
Эффект управления переменной OUT будет таким же, как и до ошибочного изменения индекса.
Если это кратковременный сбой, то система не отреагирует на ошибку и продолжит стабильно работать.
Теперь представим, что одну и ту же задачу выполняют разные программы на других языках программирования, и сравним результаты.
Код без ошибочного индекса выполняется одинаково во всех языках программирования и переменная OUT всегда имеет значение 15. Мы будем рассматривать только тот код, где закралась ошибка со стартовым значением индекса -1.
JavaScript
var IN = [ 1, 2, 3, 4, 5 ];
var OUT = 0;
for (var i = -1; i <= 4; i++) {
OUT += IN[i];
}
console.log('OUT = '+ OUT);
ВЫХ = НЭН
Идти
package main
import "fmt"
func main() {
IN := [5]int{ 1, 2, 3, 4, 5 }
OUT := 0
for i := -1; i <= 4; i++ {
OUT += IN[i]
}
fmt.Printf("OUT = %d", OUT)
}
паника: ошибка выполнения: индекс вне диапазона
Джава
public class MyClass {
public static void main(String args[]) {
int[] IN = {1, 2, 3, 4, 5};
int OUT = 0;
for (int i = -1; i <= 4; i++)
OUT += IN[i];
System.out.printf("OUT = %d", OUT);
}
}
Исключение в потоке «основной» java.lang.ArrayIndexOutOfBoundsException: -1
PHP
<Эphp
$IN = [1, 2, 3, 4, 5];
$OUT = 0;
for ($i=-1; $i<=4; $i++) {
$OUT += $IN[$i];
}
echo('OUT = '.
$OUT);
ВЫХОД = 15 Примечание PHP: неопределенное смещение: -1
Питон 3
IN = [ 1, 2, 3, 4, 5 ];
OUT = 0;
for i in range(-1, 5):
OUT += IN[i];
print('OUT = {0:1d}'.
format(OUT));
ВЫХОД = 20Python поддерживает отрицательные индексы, а нумерация начинается с конца массива.
С/С++
#include<stdio.h>
int main() {
int IN[]= {1,2,3,4,5};
int OUT=0;
int i;
for (i=-1; i<=4; i++) {
OUT += IN[i];
}
printf("OUT = %i", OUT);
return 0;
}
С языком C++ ситуация другая.
Если вы захотите проверить этот пример на популярных сайтах, вы получите следующие результаты: http://codepad.org
ВЫХ = -143484461https://ideone.com/ и так далее.
ВЫХОД = 15https://www.jdoodle.com
ВЫХОД=14В этой статье я не буду вдаваться в подробности о том, какие компиляторы C/C++ на каких платформах используются на этих сайтах.
Буду очень рада, если вы поделитесь своим мнением в комментариях.
До-диез
using System;
class Program
{
static void Main()
{
int[] IN = new int[] { 1, 2, 3, 4, 5 };
int OUT = 0;
for (int i = -1; i <= 4; i++)
{
OUT += IN[i];
}
Console.Write("OUT of IN + y = "+ OUT);
}
}
Необработанное исключение: System.IndexOutOfRangeException: индекс вышел за пределы массива.
выводы
При написании кода на любом языке программирования необходимо учитывать особенности работы со структурами данных в языке.Также учтите все места кода, где программа может аварийно завершить работу.
Зачастую после исключения код программы уже невозможно вернуть на строку, где произошла ошибка, и важные действия могут быть выполнены ниже кода.
Поэтому не все языки подходят для решения тех или иных задач или требуют дополнительных проверок и веток кода.
Языки стандарта МЭК имеют защиту от примитивных программных ошибок, так как часто некому перезагрузить программу контроллера в случае сбоя, да и эта операция в некоторых ситуациях может оказаться фатальной.
Теги: #JavaScript #java #golang #Go #php #C++ #C++ #python #программирование
-
Telegram-Бот Охраняет Порядок В Redmine
19 Oct, 24 -
Кровавая Жатва
19 Oct, 24 -
Makefile Для Самых Маленьких
19 Oct, 24 -
Результаты Компиляции На Iphone
19 Oct, 24