Непонятное поведение в строке от оболочки генератора случайных чисел (C ++) - PullRequest
1 голос
/ 21 апреля 2009

У меня есть простая обертка для генератора случайных чисел Мерсена. Цель состоит в том, чтобы масштабировать число, возвращаемое генератором (между 0 и 1), между заданными пределами аргумента (начало и конец).

Так что моя функция

inline float xlRandomFloat(float begin, float end) {return (begin+((end-begin)*genrand_real2()));}

Я не верю, что реализация функции genrand_real2 () важна, но если я ошибаюсь, ее можно найти здесь

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

Так что, если я вызову xlRandomFloat (5,10) - я получу значения от 0 до 5.

Если я отлаживаю с GDB и использую функцию печати, тогда он показывает правильный результат. Тогда я попытался разделить вещи на строки, чтобы увидеть, что происходит

inline float xlRandomFloat(float begin, float end) {
    float ret;
    ret=(((end-begin)*genrand_real2()));
    ret+=begin;
    return ret;};

При отладке он сразу переходил с первой строки в функцию genrand_real2 () и полностью пропускал все остальное. Это действительно сбивало с толку, поэтому я подумал, что это как-то связано с встраиванием. Я переместил файл из этого файла .hpp в .cpp и удалил ключевое слово inline, и все работает правильно.

Но почему это происходит, и как я могу встроить эту функцию? Кроме того, я не уверен, что это актуально, но часто, когда я вносил изменения в источники, моя компиляция Make говорила, что ничего не поделаешь. Что необычно, так как обычно я ожидаю, что make обнаружит изменения в исходных текстах и ​​перестроит их соответствующим образом.

Любые идеи.

Спасибо

Зенна

Ответы [ 2 ]

1 голос
/ 21 апреля 2009

Хорошо, здесь работают несколько вещей.

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

ret=(((end-begin)*genrand_real2()));

и первый шаг на этом вызове genrand_real2(). Если genrand_real2() является также встроенным, то вы получите первое утверждение, без паузы, чтобы отдышаться.

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

Thrd, сделайте очень простую программу со встроенным и убедитесь, что она ведет себя так, как вы ожидаете.

1 голос
/ 21 апреля 2009

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

Чтобы увидеть, является ли встраивание причиной проблемы, просто отключите все оптимизации, используя параметр -O0 (dash capital-oh zero) с GCC. Также обязательно включите символы отладки с -g.

...