C++, C2447 '{': missing function header (old-style format list?), win32 and long

218 Views Asked by At

I'm getting an error while building a solution on existing code for learning. The preprocessor I have defined is Win32 (as it should) and the code itself is from https://www.nayuki.io/page/bitcoin-cryptography-library. The error seems to be created by a long value that can be the cause for this error (win32 in use and not win64). I have tried to overcome writing it in different ways (using long/ulong/int) but no success.

static long long opsCount;

void countOps(long n){
    opsCount += n;
}

Any suggestions how to write this some other way(s) and solving this bad weather in the Error List?

/* 
 * A runnable main program that calculates and prints the approximate
 * number of 32-bit arithmetic operations needed to perform
 * elliptic curve point multiplication, in this C++ implementation.
 * 
 * Bitcoin cryptography library
 * Copyright (c) Project Nayuki
 * 
 * https://www.nayuki.io/page/bitcoin-cryptography-library
 * https://github.com/nayuki/Bitcoin-Cryptography-Library
 */

#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <string>
#include "CountOps.hpp"
#include "CurvePoint.hpp"
#include "Ecdsa.hpp"
#include "FieldInt.hpp"
#include "Sha256.hpp"
#include "Sha256Hash.hpp"
#include "Uint256.hpp"


static long long opsCount;


void countOps(long n){
    opsCount += n;
}



static void printOps(const char *name);
static void doUint256();
static void doFieldInt();
static void doCurvePoint();
static void doEcdsa();


int main() {
    doUint256();
    doFieldInt();
    doCurvePoint();
    doEcdsa();
    return EXIT_SUCCESS;
}


static void doUint256() {
    {
        Uint256 x = Uint256::ONE;
        Uint256 y = Uint256::ONE;
        opsCount = 0;
        x.replace(y, 1);
        printOps("uiReplace");
    }
    {
        Uint256 x = Uint256::ONE;
        Uint256 y = Uint256::ONE;
        opsCount = 0;
        x.swap(y, 1);
        printOps("uiSwap");
    }
    {
        Uint256 x = Uint256::ONE;
        Uint256 y = Uint256::ONE;
        opsCount = 0;
        x == y;
        printOps("uiEquals");
    }
    {
        Uint256 x = Uint256::ONE;
        Uint256 y = Uint256::ONE;
        opsCount = 0;
        x < y;
        printOps("uiLessThan");
    }
    {
        Uint256 x = Uint256::ONE;
        Uint256 y = Uint256::ONE;
        opsCount = 0;
        x.add(y);
        printOps("uiAdd");
    }
    {
        Uint256 x = Uint256::ONE;
        Uint256 y = Uint256::ONE;
        opsCount = 0;
        x.subtract(y);
        printOps("uiSubtract");
    }
    {
        Uint256 x = Uint256::ONE;
        opsCount = 0;
        x.shiftLeft1();
        printOps("uiShiftLeft1");
    }
    {
        Uint256 x = Uint256::ONE;
        opsCount = 0;
        x.shiftRight1();
        printOps("uiShiftRight1");
    }
    {
        Uint256 x = Uint256::ONE;
        Uint256 y = CurvePoint::ORDER;
        opsCount = 0;
        x.reciprocal(y);
        printOps("uiReciprocal");
    }
    std::cout << std::endl;
}


static void doFieldInt() {
    {
        FieldInt x(Uint256::ONE);
        FieldInt y(Uint256::ONE);
        opsCount = 0;
        x.replace(y, 1);
        printOps("fiReplace");
    }
    {
        FieldInt x(Uint256::ONE);
        FieldInt y(Uint256::ONE);
        opsCount = 0;
        x == y;
        printOps("fiEquals");
    }
    {
        FieldInt x(Uint256::ONE);
        FieldInt y(Uint256::ONE);
        opsCount = 0;
        x < y;
        printOps("fiLessThan");
    }
    {
        FieldInt x(Uint256::ONE);
        FieldInt y(Uint256::ONE);
        opsCount = 0;
        x.add(y);
        printOps("fiAdd");
    }
    {
        FieldInt x(Uint256::ONE);
        FieldInt y(Uint256::ONE);
        opsCount = 0;
        x.subtract(y);
        printOps("fiSubtract");
    }
    {
        FieldInt x(Uint256::ONE);
        opsCount = 0;
        x.multiply2();
        printOps("fiMultiply2");
    }
    {
        FieldInt x(Uint256::ONE);
        FieldInt y(Uint256::ONE);
        opsCount = 0;
        x.multiply(y);
        printOps("fiMultiply");
    }
    {
        FieldInt x(Uint256::ONE);
        opsCount = 0;
        x.square();
        printOps("fiSquare");
    }
    {
        FieldInt x(Uint256::ONE);
        opsCount = 0;
        x.reciprocal();
        printOps("fiReciprocal");
    }
    std::cout << std::endl;
}


static void doCurvePoint() {
    {
        CurvePoint x = CurvePoint::G;
        CurvePoint y = CurvePoint::G;
        opsCount = 0;
        x.replace(y, 1);
        printOps("cpReplace");
    }
    {
        CurvePoint x = CurvePoint::G;
        opsCount = 0;
        x.isZero();
        printOps("cpIsZero");
    }
    {
        CurvePoint x = CurvePoint::G;
        CurvePoint y = CurvePoint::G;
        opsCount = 0;
        x == y;
        printOps("cpEquals");
    }
    {
        CurvePoint x = CurvePoint::G;
        opsCount = 0;
        x.twice();
        printOps("cpTwice");
    }
    {
        CurvePoint x = CurvePoint::G;
        CurvePoint y = CurvePoint::G;
        opsCount = 0;
        x.add(y);
        printOps("cpAdd");
    }
    {
        CurvePoint x = CurvePoint::G;
        Uint256 y = Uint256::ONE;
        opsCount = 0;
        x.multiply(y);
        printOps("cpMultiply");
    }
    {
        CurvePoint x = CurvePoint::G;
        opsCount = 0;
        x.normalize();
        printOps("cpNormalize");
    }
    {
        CurvePoint x = CurvePoint::G;
        opsCount = 0;
        x.isOnCurve();
        printOps("cpIsOnCurve");
    }
    std::cout << std::endl;
}


static void doEcdsa() {
    {
        Uint256 privKey = Uint256::ONE;
        Sha256Hash msgHash = Sha256::getHash(nullptr, 0);
        Uint256 nonce = Uint256::ONE;
        Uint256 outR, outS;
        opsCount = 0;
        Ecdsa::sign(privKey, msgHash, nonce, outR, outS);
        printOps("edSign");
    }
    {
        CurvePoint pubKey = CurvePoint::G;
        Sha256Hash msgHash = Sha256::getHash(nullptr, 0);
        Uint256 r = Uint256::ONE;
        Uint256 s = Uint256::ONE;
        opsCount = 0;
        Ecdsa::verify(pubKey, msgHash, r, s);
        printOps("edVerify");
    }
    std::cout << std::endl;
}


static void printOps(const char *name) {
    std::string s = std::to_string(opsCount);
    while (s.size() < 9)
        s.insert(0, " ", 1);
    for (std::size_t i = s.size(); i >= 4; i -= 3)
        s.insert(i - 3, " ", 1);
    std::cout << s << "  " << name << std::endl;
}

Here are the errors:

image

1

There are 1 best solutions below

0
Anon Coward On

For future reference, you should work on making your example a good Minimal, Reproducible Example. This will not only enhance the chances you get a response on Stack Overflow, but very likely make it so you can start fixing problems yourselves.

For instance, this is the single function you're having problems with:

#define countOps(n)
static long long opsCount;
void countOps(long n){
    opsCount += n;
}

If you try to compile just that in a .cpp file, it'll work, though complain about a lack of an entry point. So, so #include must be causing an issue. The obvious candidate is CountOps.hpp where this is declared. In this case, unless you #define COUNT_OPS, the header will be just

#define countOps(n)

So if we put these two pieces together, we have a minimal, reproducible example of your compile error:

#define countOps(n)
static long long opsCount;
void countOps(long n){
    opsCount += n;
}

In other words, the included file is attempting to #define away the countOps function to nothing, and by implementing it, the preprocessor is turning your code into

static long long opsCount;
void {
    opsCount += n;
}

Which makes no sense. You can fix this by either #define COUNT_OPS before you include CountOps.hpp, or simply not bothering to try and create this function. The correct path depends on how this library is meant to be used.

My point isn't to tell you how to fix this problem, but hopefully help you understand how to detect it in the future, so you can understand what's happening, and why it's happening, or at least help others trying to help you.

And one final point: Assume your images won't ever be seen. Not only will some users have trouble seeing them, but another user searching for your problem in the future won't see it, so it lessons the ability for others to learn from your question. Your compiler will emit these errors at text at some level. You should copy-n-paste from there.