vpiotr / decimal_for_cpp

Decimal data type for C++
273 stars 68 forks source link

INT32_MAX on linux #5

Closed VioletDarkKitty closed 10 years ago

VioletDarkKitty commented 10 years ago

Linux seems to not use INT32_MAX, I have added

#ifdef __linux__
    #define INT32_MAX INT_MAX
#endif

To the top of the header and this lets it compile.

vpiotr commented 10 years ago

This is not 100% true. It compiles fine on Linux and on Gcc/Win. What kind of Linux you are using? Try to find stdint.h file and verify what is inside.

VioletDarkKitty commented 10 years ago

It was ubuntu, the stdint.h file (/usr/include/c++/4.8/tr1/stdint.h) only includes tr1/cstdint and the other (/usr/include/stdint.h) does have it defined. Should I be including stdint or should the decimal header be including it?

vpiotr commented 10 years ago

decimal.h should include stdint.h, but only if you didn't define DEC_EXTERNAL_LIMITS. If including stdint.h before decimal.h helps, try to correct #ifdef code inside decimal.h so it works for you, without including stdint.h before decimal.h.

VioletDarkKitty commented 10 years ago
#include "decimal.h"
using namespace dec;

Is all I'm using to include the decimal header, nothing before it. Im going to mess around with the ifdefs to see if i can get it to work, ill post back here if i can get it working without that define.

VioletDarkKitty commented 10 years ago

Ok, changing the whole section to this:

#ifndef DEC_EXTERNAL_LIMITS
#include <limits.h>
#define INT32_MAX INT_MAX
#endif

seems to fix the problem. I dont know if you want to include this, it might be a C99 error or something.

vpiotr commented 10 years ago

This is wrong way. stdint.h file should define INT32_MAX, but it needs __STDC_LIMIT_MACROS before including it. Maybe something else makes this symbol not importable. Try with basic "hello world" program generated from IDE (for example Code::Blocks).

VioletDarkKitty commented 10 years ago

Still errors, here is the full error log: ||=== decimal, Debug ===| ../../../include/decimal.h|311|error: ‘INT32_MAX’ was not declared in this scope| ../../../include/decimal.h|331|warning: control reaches end of non-void function [-Wreturn-type]| ../../../include/decimal.h|331|warning: control reaches end of non-void function [-Wreturn-type]| ../../../include/decimal.h|331|warning: control reaches end of non-void function [-Wreturn-type]| ../../../include/decimal.h|331|warning: control reaches end of non-void function [-Wreturn-type]| ||=== Build finished: 1 errors, 4 warnings (0 minutes, 3 seconds) ===|

vpiotr commented 10 years ago

But you can include stdint.h and use it in the same project?

vpiotr commented 10 years ago

Try to compile new project with this code (without decimal.h): http://ideone.com/Qw6usD

VioletDarkKitty commented 10 years ago

Just including stdint.h still gives the error.

VioletDarkKitty commented 10 years ago

That test code works, gives the output: Max is: 2147483647 I've got no idea why the test program doesn't work though.

vpiotr commented 10 years ago

This test program doesn't work with stdint.h enabled?

VioletDarkKitty commented 10 years ago

http://ideone.com/Qw6usD works fine but I can't get the codeblocks build program to compile.

vpiotr commented 10 years ago

Well, I have installed Ubuntu 13 and it works for me... What I have installed after OS setup: 1) Code::Blocks 2) g++ using command "sudo apt-get install g++" 3) Code::Blocks needed a setup change in: Settings\Compiler\Toolchain executables \ Compiler's installation directory changed to: /usr/bin

And that is, basic program which works with current version of decimal.h:

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

using namespace std;
using namespace dec;

int main()
{
    cout << "Max is: " << INT32_MAX << endl;
    decimal<4> d = decimal_cast<4>(123.3451);
    cout << "Decimal: " << d << endl;
    return 0;
}
VioletDarkKitty commented 10 years ago

I'm going to try getting this working, one sec

VioletDarkKitty commented 10 years ago

Ok, im still getting errors with that program. ||=== decimal, Debug ===| ../../../include/decimal.h|304|error: ‘INT32_MAX’ was not declared in this scope| .../decimal_for_cpp-master/tests/decimalTest.cpp||In function ‘int main()’:| .../decimal_for_cpp-master/tests/decimalTest.cpp|9|error: ‘INT32_MAX’ was not declared in this scope| ||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===| Any ideas? Could it be a problem with 64bit?

vpiotr commented 10 years ago

I have 64bit OS. Try: uname -a

VioletDarkKitty commented 10 years ago

Linux Verbatium 3.10.26-031026-generic #201401091635 SMP Thu Jan 9 21:36:30 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

vpiotr commented 10 years ago

And this compiles without any problems or warnings?

#include <iostream>
#define __STDC_LIMIT_MACROS
#include <stdint.h>

using namespace std;

int main()
{
    cout << "Max is: " << INT32_MAX << endl;
    return 0;
}
VioletDarkKitty commented 10 years ago

Yes, that compiles ok.

vpiotr commented 10 years ago

OK,

1) in decimal.h change this:

#ifndef DEC_EXTERNAL_LIMITS
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#undef __STDC_LIMIT_MACROS
#else
#include <stdint.h>
#endif
#endif

to this:

#ifndef DEC_EXTERNAL_LIMITS
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#endif 

2) and use this test program:

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

using namespace std;
using namespace dec;

int main()
{
    decimal<4> d = decimal_cast<4>(123.3451);
    cout << "Decimal: " << d << endl;
    return 0;
}
VioletDarkKitty commented 10 years ago

That did it. Its working now

VioletDarkKitty commented 10 years ago

Doing that in my project still gives that error though...

VioletDarkKitty commented 10 years ago

Right, ive got it working. I had all these includes before the include for decimal:

#include <map>
#include <string>
#include <iostream>
#include "functions.h"
#include "globals.h"
#include <cstdlib> // 
#include <cstdio> //  for system() exit() etc
#include <ctype.h>
#include "parseLine.h"
#include "ExceptionWithStack.h"
#include <cstring>
#include <math.h>
#include "md5.h"
#ifdef WIN32
    #include <windows.h>
    #include <direct.h>
    #include <time.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <unistd.h>
#include "sha2.h"
#include "stdlib.h"

So I put the decimal stuff at the top of the file and now it compiles

vpiotr commented 10 years ago

When you add comment here with code use "Fenced code blocks" as described here: https://help.github.com/articles/github-flavored-markdown

Try to find a way of using decimal.h without changes inside it, otherwise you will have to modify it every time new version appears.

Also it looks like you have included stdlib twice:

VioletDarkKitty commented 10 years ago

My windows build is throwing errors too now...

I have a proposed fix because INT32_MAX is not being defined and INT_MAX is. They're the same constant and the stdlib headers are not standard (http://stackoverflow.com/questions/3233054/error-int32-max-was-not-declared-in-this-scope)

#ifndef DEC_EXTERNAL_LIMITS
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#ifndef INT32_MAX
    #ifdef INT_MAX
        #define INT32_MAX INT_MAX
    #else
        #error "Failed to define INT32_MAX!"
    #endif
#endif
#endif

Should be added at line 34 to make sure that INT32_MAX is defined.

To make it work without the changes in decimal.h:

#define DEC_EXTERNAM_LIMITS
#define __STDC_LIMIT_MACROS
#include <cstdlib>
#include "decimal.h"

Should work.

vpiotr commented 10 years ago

OK, I think you found a weak part of standard.

stdint.h is part of C99 standard and cstdint is part of C++11 standard. See: http://stackoverflow.com/questions/13642827/cstdint-vs-stdint-h

And also it is undefined how to check if compiler supports C++11 standard in a portable way.

Try to change inside decimal.h this part:

#ifndef DEC_EXTERNAL_LIMITS
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#undef __STDC_LIMIT_MACROS
#else
#include <stdint.h>
#endif
#endif

into this:

#ifndef DEC_EXTERNAL_LIMITS

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#if defined(__GXX_EXPERIMENTAL_CXX0X) || (__cplusplus >= 201103L)
#include <cstdint>
#else
#include <stdint.h>
#endif

#endif

After this change you code should work with only:

#include "decimal.h"
VioletDarkKitty commented 10 years ago

That still doesn't work, http://pastebin.com/drS0Khqz is the stdint.h file I have on this system. It should be defining it but it isn't.

vpiotr commented 10 years ago

OK, I see what is wrong. stdint.h will define INT32_MAX but only if you:

So, solution is to define this symbol on project level. This should fix your problem (without any changes in code of decimal.h).

VioletDarkKitty commented 10 years ago

Ok, that fixed it. I'm not including stdint.h anywhere else though. Weird.

vpiotr commented 10 years ago

It's part of standard, so probably included third-party files are using it somehow.