Почему указатель не наследует фиксированный размер строкового литерала - PullRequest
0 голосов
/ 04 мая 2019

Есть ли какая-либо скрытая особенность ключевого слова sizeof, которое мне здесь не хватает, когда оно применяется к литералу, а не к указателю , инициализированному для другого литерала ?

#include <iostream>

int main(int argc, char* argv[]) {
    const char* string = "Hello, World!";

    // sizeof(...) on literal; returns 14 (the actual length)
    std::cout << "sizeof (with literal): " << sizeof("Hello, World!") << std::endl;

    // sizeof(...) on initiated pointer; returns 4 (wonder why?)
    std::cout << "sizeof (with variable): " << sizeof(string) << std::endl;

    return 0;
}

Или это просто мой компилятор "оптимизирующий" источник?


Вопрос здесь может показаться ответом на мой вопрос, но только частично .

В представленном ответе отмечается, что C ++ не может передавать целые массивы в качестве параметров функции и, таким образом, вместо этого получает аргументы массива в виде указателей
(Что логически, указатели аргументов могут быть любого размера).

На что я могу догадаться, что литерал , вероятно, оптимизирован как массив фиксированного размера , а указатель имеет произвольный размер во время компиляции, но вопрос: почему ?


Проще обернуть голову вокруг этого, если переменная была неинициализирована:
char* string; // Arbitrary size that's mutable (usually 4 bytes)

но не в этом случае, когда его инициализируют в литерал фиксированного размера:
const char* string = "Hello, World!"; // Fixed-size of 14 allocated to variable?

После того, как все действительные символы переменной были указаны при инициализации (которая неявно дает длину по числу инициализированных символов) , не приведет ли переменная к наследованию выделенного размера литерала?

Ответы [ 2 ]

2 голосов
/ 04 мая 2019

На что я могу предположить, что литерал, вероятно, оптимизирован как массив фиксированного размера

Литерал не "оптимизирован", чтобы быть массивом фиксированного размера.Строковый литерал - это массив фиксированного размера: это не вопрос оптимизации.

, а указатель имеет произвольный размер во время компиляции

Непонятно, что вы подразумеваете под "произвольным".Размер указателя данных определяется целевой системой.В 64-битной системе x86 размер указателя составляет, например, 8 байт.

const char* string = "Hello, World!"; // Fixed-size of 14 allocated to variable?

То, на что указывает указатель, не влияет на размер указателя.

не приведет ли переменная к наследованию выделенного размера литерала?

Единственное, что влияет на размер переменной, - это тип переменной.Если тип переменной const char*, то размер этой переменной точно такой же, как sizeof(const char*).

1 голос
/ 04 мая 2019

Указатель - это указатель, а его размер равен размеру указателя, независимо от того, на что он указывает. Инициализация указателя для указания строкового литерала не меняет этого - это все же указатель.

Не объединяйте массивы и указатели. Это две разные вещи. Имя массива в большинстве контекстов превращается в указатель на его первый элемент, и это часто смущает новичков. Одна из ситуаций, когда имя массива не превращается в указатель, - это когда имя является аргументом оператора sizeof. Вот почему sizeof “abcdef” равно 7, а не размер указателя.

...