Может ли глобальные массивы в C ++ нарушать двоичную совместимость? - PullRequest
3 голосов
/ 24 декабря 2009

Допустим, общая библиотека содержит следующие строки:

const char* const arr[] =
{
  "one",
  "two",
  "three"
};

1) Может ли приложение ссылаться на эту библиотеку и использовать символ «arr»?

2) Нарушена ли двоичная совместимость, если в определение добавлен новый элемент?

3) Как насчет изменения одного из строковых литералов?

4) Почему (нет)?

Cheers, Люк

Ответы [ 4 ]

5 голосов
/ 24 декабря 2009

Двоичная совместимость не нарушается ни в одном случае.

Массивы в стиле C не хранят и не делают предположений о длине массива, поэтому увеличение длины массива не нарушит никаких предположений.

У вас есть массив указателей , поэтому изменение строкового литерала вообще не повлияет на макет памяти вашего массива.

5 голосов
/ 24 декабря 2009

1) Да

2) Нет

3) Не проблема

4) Почему вы думаете иначе?

4 голосов
/ 24 декабря 2009

1) Да, при условии, что он объявил extern (обратите внимание, что const объекты имеют статическую связь по умолчанию; да, это нелогично;)).

2) Зависит от того, как этот arr используется кодом, который на него ссылается. Если вы хотите, чтобы новые записи были полезны для внешнего кода, либо arr должен заканчиваться NULL, либо он должен сопровождаться extern const unsigned arr_size = sizeof(arr) / sizeof(arr[0]).

3) Хорошо. Сам массив состоит из указателей на литеральное представление; если изменяется литерал, расположение самого массива не изменится.

4) Нет, потому что arr - это непрерывная последовательность указателей на литеральные представления, вот и все.

4 голосов
/ 24 декабря 2009

Символ arr указывает на основание массива независимо от того, какие элементы находятся в массиве. Вы можете изменить количество элементов или значение одного или нескольких элементов, и символ arr по-прежнему будет указывать на начало массива.

Однако приложению может потребоваться дополнительная информация о arr: оно, вероятно, хочет знать, сколько в нем элементов.

Либо завершите список пустым указателем, либо экспортируйте размер:

const size_t arrSize = sizeof(arr)/sizeof(char*);
...