Ошибки при добавлении cpp файла

190
02 февраля 2018, 22:21

Пытаюсь подключить другие cpp файлы. При добавлении выдает ошибки:

LNK2005 "__int64 __cdecl powmod(__int64,__int64,__int64)" (?powmod@@YA_J_J00@Z) уже определен   
LNK2005 "__int64 __cdecl powmod(__int64,__int64,__int64)" (?powmod@@$$FYA_J_J00@Z) уже определен в Pollard.obj  all_metods  
LNK1169 обнаружен многократно определенный символ - один или более  all_metods  

Код файла Shenks.cpp:

#include <iostream>
#include <math.h>
#include "methods.h"
#include <map>
using namespace std;
__int64 powmod(__int64 a, __int64 b, __int64 m) {
    __int64 res = 1;
    while (b > 0)
        if (b & 1) {
            res = (res * a) % m;
            --b;
        }
        else {
            a = (a * a) % m;
            b >>= 1;
        }
        return res % m;
}
__int64 Shenks(__int64 a,__int64 b,__int64 m) {
    __int64 n = (__int64)sqrt(m) + 1;
//  __int64 *r;
//  r = new __int64[n];
    map<__int64,__int64> vals;
    for (__int64 i = n; i >= 1; --i)
        vals[powmod(a, i * n, m)] = i;
    for (__int64 i = 0; i <= n; ++i) {
        __int64 cur = (powmod(a, i, m) * b) % m;
        if (vals.count(cur)) {
            __int64 ans = vals[cur] * n - i;
            if (ans < m)
                return ans;
        }
    }
    return -1;
}

Код файла Pollard.cpp:

#include <iostream>
#include "methods.h"
#include <vector>
using namespace std;
__int64 powmod(__int64 a, __int64 b, __int64 m) {
    __int64 res = 1;
    while (b > 0)
        if (b & 1) {
            res = (res * a) % m;
            --b;
        }
        else {
            a = (a * a) % m;
            b >>= 1;
        }
        return res % m;
}
__int64 gcdex(__int64 a, __int64 b, __int64 &x, __int64 &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    __int64 x1, y1;
    __int64 d1 = gcdex(b, a % b, x1, y1);
    x = y1;
    y = x1 - (a / b) * y1;
    return d1;
}
__int64 ReverseElement(__int64 a, __int64 N) {
    __int64 x, y, d;
    d = gcdex(a, N, x, y);
    if (d != 1) {
        return 1;
    }
    else
        return x;
}
__int64 NOD(__int64 a, __int64 b)
{
    while (a > 0 && b > 0)
        if (a > b)
            a %= b;
        else
            b %= a;
    return a + b;
}
__int64 phi(__int64 n) {
    __int64 result = n;
    for (__int64 i = 2; i*i <= n; ++i)
        if (n % i == 0) {
            while (n % i == 0)
                n /= i;
            result -= result / i;
        }
    if (n > 1)
        result -= result / n;
    return result;
}
__int64 Pollard(__int64 a, __int64 b, __int64 p)
{
    vector<__int64> z(214783640), u(214783640), v(214783640);
    z[0] = 1;
    __int64 ph = phi(p);
    __int64 ak = 0, ev = 0, eu = 0, nod, chk;
    __int64 p1 = p - 1;
    __int64 x = 0;
    for (__int64 i = 0; i < p; i++)
    {
        if (z[i] % 3 == 1)
        {
            z[i + 1] = b * z[i] % p;
            u[i + 1] = u[i] % ph;
            v[i + 1] = (v[i] + 1) % ph;
        }
        if (z[i] % 3 == 2)
        {
            z[i + 1] = z[i] * z[i] % p;
            u[i + 1] = 2 * u[i] % ph;
            v[i + 1] = 2 * v[i] % ph;
        }
        if (z[i] % 3 == 0)
        {
            z[i + 1] = a * z[i] % p;
            u[i + 1] = (u[i] + 1) % ph;
            v[i + 1] = v[i] % ph;
        }
        if (*find(z.begin(), z.begin() + i, z[i + 1]) != *(z.begin() + i))
        {
            ak = distance(z.begin(), find(z.begin(), z.begin() + i, z[i + 1]));
            ev = v[ak] - v[i + 1];
            if (ev < 0)
                ev += p1;
            eu = u[i + 1] - u[ak];
            if (eu < 0)
                eu += p1;
            nod = NOD(ev, p1);
            ev /= nod;
            eu /= nod;
            p1 /= nod;
            chk = ReverseElement(ev, p1);
            if (chk < 0)
                chk += p1;
            x = chk*eu%p1;
            if (powmod(a, x, p) != b)
                x += p1;
            break;
        }
    }
    return x;
}

Как я понял, потому что используется одинаковая функция powmod. Как правильно исправить?

Answer 1

Да, дело именно в двойном определении powmod.

Если заведомо известно, что в обоих случаях нужна именно одна и та же функция (как в данный момент)

  1. Если функция внешняя, т.е. возможно нужна и другим модулям проекта, то одну убрать, другую оставить.
  2. Если функция чисто внутренняя для модуля, то, возможно, ради сохранения независимости модулей стоит сохранить обе копии, но объявить их static (или заключить в безымянный namespace). Сделать то же самое и с другими внутренними по своей сути функциями.

Если же эти функции совпали чисто случайно, то переименовать их, чтобы устранить совпадение имен.

READ ALSO
Не работает дружественная функция

Не работает дружественная функция

В книге Герберта Шилдта используется такой пример :

167
Присвоение в описании класса

Присвоение в описании класса

В какой момент времени во время исполнения произойдет присвоение int a = 5?

178
Ошибка в работе со стеком LUA из C++

Ошибка в работе со стеком LUA из C++

ПриветствуюРаботаю со скриптом LUA и C++

178
Периодически вызываемый GetProcessTime выдаёт одно и то же значение

Периодически вызываемый GetProcessTime выдаёт одно и то же значение

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

178