2017-02-13 3 views
1

В стандартной библиотеке C++ ios гарантируется, что &stream.iword(ind) != &stream.pword(ind) при вызове на том же stream с тем же значением ind?С учетом того же индекса, iword() и pword() гарантированно относятся к отдельным базовым значениям?

Кроме того, гарантировано, что я могу использовать значения void* и long индивидуально с учетом того же индекса (т. Е. Они не реализованы как объединение и т. Д.)?

Я полагаю, что проблема X-Y здесь в том, как я знаю, было ли инициализировано мое заданное значение («выделено» с использованием xalloc()), если задан случайный поток? Я спрашиваю, потому что я видел, как люди использовали pword(), чтобы проверить магическую константу, а затем iword(), чтобы инициализировать это значение, если предыдущее условие выходит из строя.

В основном я забочусь о C++ 11 и далее, хотя любая соответствующая историческая информация приветствуется.

+0

Ссылка, возвращаемая 'iword()', недействительна при вызове 'pword()', поэтому я не уверен, что адреса могут быть осмысленно сопоставлены. – Cornstalks

+0

@Cornstalks Интересно; как это признано недействительным?Вы имеете в виду, что вы можете использовать 'pword()' или 'iword()', но не оба? – Qix

+0

Вот некоторая (не авторитетная, но очень полезная) документация по ['iword'] (http://en.cppreference.com/w/cpp/io/ios_base/iword) и [' pword'] (http://en.cppreference.com/w/cpp/io/ios_base/pword). Для обоих этих методов обратите внимание на предложение * «Ссылка может быть аннулирована любой операцией на этом объекте« ios_base »[...]» *. Вы можете использовать один из них, но как только вы вызываете следующую функцию, вам нужно отменить свою прежнюю ссылку и больше не использовать ее. Подумайте о том, как это сделать адрес объекта в 'std :: vector'. Это нормально, но как только вы назовете 'push_back', этот адрес может быть недействительным. – Cornstalks

ответ

1

стандарт C++ говорит, что iword() и pword() должны вести себя так, как будто они управляют две отдельные, независимые блоки памяти - скорее, чем, скажем, один блок, содержимое которого интерпретируются как long иногда и void* другие времена.

[ios.base]

namespace std { 
    class ios_base { 
    // ... 
    private: 
    long* iarray; // exposition only 
    void** parray; // exposition only 
    }; 
} 

[ios.base.storage]/3

long& iword(int idx); 

эф ts: Если iarray является нулевым указателем, выделяет массив из long неуказанного размера и сохраняет указатель на его первый элемент в iarray. Затем функция расширяет массив, на который указывает iarray, при необходимости, чтобы включить элемент iarray[idx]. Каждый вновь выделенный элемент массива инициализируется равным нулю. Возвращенная ссылка недействительна после любых других операций над объектом. Тем не менее, стоимость хранения упомянутых сохраняется, так что до следующего вызова copyfmt, вызывающего iword с тем же индексом не дает еще одну ссылку на ту же величину ...

[ios.base.storage ]/5 повторяет ту же формулировку, заменяя pword на iword, parray на iarray и void* на long.

Важная часть: «значение хранения ... сохраняется» - последующий вызов iword с заданным индексом должен видеть значение, которое было записано в хранилище, которое предыдущий вызов iword с тем же индексом, при условии, что ссылка на, независимо от интервенционных вызовов метода (кроме copyfmt), даже если этот вызов промежуточного метода равен pword (и наоборот).

Смежные вопросы