Подтвердить что ты не робот

Ошибка, которая исчезает при попытке изучить ее

Это самая странная вещь, которая когда-либо случалась со мной при программировании на С++.

Это мой основной файл:

#include <iostream>
#include "lib/utils.h"

using namespace std;

int main(int argc, const char *argv[]) {
    cout << bin2dec(101000010);
    return 0;
}

и это lib/utils.cpp:

#include <iostream>
#include "utils.h"

int bin2dec(int bin) {
    // 101000010
    int dec;
    //std::cout << "";  // If you uncomment this, it works.
    for (int i = 1; bin > 0; i *= 2, bin /= 10) {
        if (bin % 2 == 1) {
            dec += i;
        }
    }
    return dec;
}

Программа компилируется без предупреждений, а при запуске она выводит 450. 450 не равно 101000010 в десятичном значении, 322 есть. Первая странная вещь заключается в том, что разница между 482 и 322 равна 128. Это происходит с любым двоичным числом, которое вы пытаетесь преобразовать. Но что ДЕЙСТВИТЕЛЬНО странно, это то, что когда я пытался вывести значение bin и dec внутри for в попытке отладки функции, он внезапно начал работать правильно.

В принципе, по какой-то причине, если вы std::cout что-то перед возвратом функции, оно работает. Если вы этого не сделаете, он добавит 128 к результату.

Я использую g++ 4.6.0 и компилирую вот так:

g++ -c   -D NDEBUG -O2     -o 10.o 10.cpp
g++ -c   -D NDEBUG -O2     -o lib/utils.o lib/utils.cpp
g++  -o 10   -Wl,-S  10.o lib/utils.o lib/menu.o 
4b9b3361

Ответ 1

Вы не инициализируете dec.

int dec = 0;

Ответ 2

Небольшая ошибка заключается в том, что вы не инициализируете переменную dec.

Большая ошибка заключается в том, что вы не используете для добавления -Wall и -O2 при компиляции (что может вызвать большую боль, поскольку программы, которые вы пишете, станут более сложными).

-Wall разрешает все предупреждения и -O2 требует оптимизации (оптимизация включает анализ пути кода, который вызывает предупреждения о неинициализированных переменных).

Ответ 3

int dec;

Создает dec, но никогда не дает ему начальное значение (например, 0). Затем вы добавляете в него значения и получаете случайный результат.

Ответ 4

Вам нужно инициализировать dec до нуля в вашей функции:

int dec = 0;

Не инициализируя его, он начинается с любой случайной crud в памяти в месте переменной. И вызов cout << может повлиять на то, что crud находится в этой области, следовательно, изменения. Кстати, когда я пробовал свой код, я не получал 450. Я получил 134514688, который дает пример этого.

Ответ 5

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

Изменить: О, да, вы можете начать с инициализации dec, например.