встроенные функции, возвращающие неверные результаты

У меня есть большое приложение, над которым я работаю на C++, и у нас есть класс, в котором встроенные функции возвращают неправильное значение. Похоже, они компенсируются одной записью.

Вот пример настройки кода:

class Test
{

private:
    uint myVal1;    
    uint myVal2;
    uint myVal3;
    uint myVal4;

public:
    uint myFunct1() const { return myVal1 };
    uint myFunct2() const { return myVal2 };
};

Мы видим, что myFunct1 возвращает myVal2, а myFunct2 возвращает myVal3. Если я не использую встроенные функции, все работает, как и ожидалось.

Любые идеи о том, почему это происходит?

Заранее спасибо.


person JumboSmith    schedule 08.02.2011    source источник
comment
выглядит как неинициализированная переменная (указатель) (где-то еще в коде) для меня..   -  person thbusch    schedule 09.02.2011
comment
давайте исключим действительно глупые вещи, вы действительно уверены, что значения установлены правильно?   -  person Nim    schedule 09.02.2011
comment
да, значения определенно установлены правильно, и это не неинициализированная переменная, потому что все элементы выглядят правильно, и, как я уже сказал, если я определяю эти функции внутри файла .cpp вместо файла .h, все работает идеально   -  person JumboSmith    schedule 09.02.2011


Ответы (2)


(Я предполагаю, что то, что вы разместили выше, на самом деле является фрагментом какого-то заголовочного файла.)

Подобные вещи обычно случаются, когда разные исходные файлы в вашей программе скомпилированы с разными настройками, связанными с размещением в памяти, такими как упаковка классов и настройки выравнивания. Ваш заголовочный файл включен в эти разные единицы перевода и интерпретируется по-разному из-за расхождений в настройках макета памяти.

Как только вы начнете передавать свои Test объекты между этими единицами перевода, проблема обнаружится. Одна единица перевода создает объект Test с одной структурой памяти, затем другие единицы трансляции читают или записывают в нее, предполагая совершенно другую структуру памяти. В вашем случае это ваши встроенные функции, которые интерпретируются по-разному в каждой единице перевода.

Если вы определите свои функции-члены как невстроенные, они примут макет памяти класса, характерный для исходного файла, в котором они определены. Это заметет проблему под ковер и заставит вещи "работать" (поскольку функции доступа теперь привязаны к одному макету памяти), но, тем не менее, это все еще не очень хорошая ситуация. Это все еще может привести к различным проблемам аналогичного характера в будущем.

Убедитесь, что все исходные файлы в вашей программе скомпилированы с точно такими же настройками макета памяти класса.

P.S. Как отметил Фред в комментариях, несоответствие в расположении памяти классов между единицами перевода может быть вызвано чем-то столь же прозаичным, как забывание перекомпилировать исходный файл после изменения файла заголовка, от которого зависит исходный файл.

Другим «популярным» источником таких проблем являются определения классов, которые зависят от директив препроцессора (т. е. макет класса, «настраиваемый» #ifdef/#endif сегментами). Если вы забудете #define что-то важное в каком-либо исходном файле, который включает в себя ваш заголовочный файл, вы можете получить другую схему памяти для класса в этом исходном файле.

person AnT    schedule 09.02.2011
comment
Это также происходит, когда вы компилируете TU, изменяете заголовок, компилируете вторую TU, а затем связываете две TU вместе (без повторной компиляции первой). Другими словами, как для ситуации выше, так и для моей, ваша система сборки облажалась. Убедитесь, что вы отслеживаете зависимости заголовков. - person Fred Nurk; 09.02.2011
comment
похоже, возникла проблема с правильным отображением последнего значения выравнивания упаковки - person JumboSmith; 10.02.2011
comment
@JumboSmith, у меня такая же проблема. Как вы это решили? - person user1166419; 20.02.2018
comment
@user1166419: JumboSmith говорит, что они разбалансировали прагмы push/pop для настроек выравнивания (т. е. директивы #pragma pack(push, ...)/#pragma pack(pop, ...)). Естественно, они должны решить эту проблему, исправив дисбаланс. - person AnT; 20.02.2018

Нет, встроенные функции (конечно) должны иметь те же результаты, что и невстроенные функции. Значит, проблема должна быть где-то в другом месте, в коде, который вы не показываете. Возможно, тот, который волшебным образом устанавливает значения частных членов?

person Bo Persson    schedule 09.02.2011
comment
я не думаю, что проблема в этом, как я уже сказал, если я определяю функцию в файле .cpp, а не в файле .h, все работает нормально. - person JumboSmith; 09.02.2011
comment
@JumboSmith: Но это не должно иметь значения, поэтому проблема должна быть в другом. Могу поспорить, что ответ AndreyT - хорошая подсказка. - person Bo Persson; 09.02.2011