2011-02-08 2 views
3

У меня есть большое приложение, над которым я работаю в 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. Если я не выполняю функции, все работает так, как ожидалось.

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

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

+0

выглядит как неинициализированная переменная (указатель) (где-то еще в коде) для меня .. – thbusch

+1

давайте исключим действительно глупый материал, действительно ли вы уверены, что значения установлены правильно? – Nim

+0

Да, значения определенно заданы правильно и не являются неинициализированной переменной, потому что все члены выглядят правильно и, как я сказал, если я определяю эти функции внутри .cpp вместо.h файл все работает отлично – JumboSmith

ответ

11

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

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

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

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

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

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

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

+5

Это также происходит, когда вы компилируете TU, изменяете заголовок, компилируете второй TU, затем соединяете два TU вместе (без перекомпиляции первого). Другими словами, как для ситуации выше, так и для моей, ваша система сборки запутана. Убедитесь, что вы отслеживаете зависимости заголовков. –

+0

выглядит как проблема с правильной настройкой последнего значения выравнивания упаковки – JumboSmith

+0

@ JumboSmith- У меня такая же проблема. Как вы это разрешили? – user1166419

3

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

+0

Я не думаю, что проблема, как я сказал, если я определяю функцию в файле .cpp и не .h, все работает нормально. – JumboSmith

+2

@JumboSmith: Но это не должно иметь значения, поэтому проблема должна быть в другом месте. Я бы поспорил, что ответ AndreyT - хорошая подсказка. –

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