#cpp #строки #cpp11 #объявление #строковый_литерал
Вот пример кода: auto size = "Hello, world"; std::cout << sizeof(size); В консоль выводится 4. Не могу понять, какой тип данных использует компилятор для хранения этой строки?
Ответы
Ответ 1
Строковые литералы в C++ имеют типы константных символьных массивов. Данный литерал "Hello, world" имеет тип const char[13] Используемый в качестве выражения инициализации он неявно преобразуется к указателю на свой первый элемент, который имеет тип const char * Соответственно переменная size имеет тип const char *. Вы можете убедиться в этом, запустив на выполнение следующий фрагмент кода auto size = "Hello, world"; std::cout << typeid(size).name() << std::endl; Если бы вы написали так decltype(auto) size = "Hello, world"; std::cout << sizeof(size) << std::endl; то переменная size была бы ссылкой на строковый литерал и имела тип const char ( & )[13], а оператор sizeof вернул бы значение 13.Ответ 2
С абстрактно-наивной точки зрения в данном случае приемлемыми типами для левой части инициализации являются const char (&)[13], [const] char[13] и const char *. Поведение, соответственно, будет зависеть о того, как правила языка описывают дедукцию типа для спецификатора auto в такой декларации. Эти правила совпадают со старыми-добрыми классическими правилами дедукции типов шаблонных аргументов для шаблонных функций, которые говорят, что в данном случае должен дедуцироваться тип "указатель" (а не тип "массив" или тип "ссылка"). Т.е. произойти в данном случае должно то же самое, что и примере templatevoid foo(T) { std::cout << sizeof(T) << std::endl; } int main() { foo("Hello, world"); // специализируется как `foo ` } При желании, как в вашем случае, так и в примере с функцией выше, вы можете направить дедукцию в другом направлении auto &size = "Hello, world"; и получить size типа const char (&)[13] и sizeof, возвращающий 13. Заметьте, что ни в первом, ни во втором случае не происходит создания копии исходного строкового литерала, т.е. никакого дополнительного "хранения строки" при этом не возникает. "Хранящаяся строка" в этих случаях - это лишь исходный строковый литерал и хранится он так, как он хранился с начала времен: как статический неизменяемый объект. Ответ 3
Указатель на char sizeof(char *)
Комментариев нет:
Отправить комментарий