Login
Username:

Password:

Remember me



Lost Password?

Register now!
Sections
Who's Online
39 user(s) are online (31 user(s) are browsing Forums)

Members: 0
Guests: 39

more...
Support us!
Recent OS4 Files
OS4Depot.net





c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Home away from home
Joined:
2007/9/11 11:31
From Russia
Posts: 5882
@all
Lately found some issues in some port, and reduced it to some test case which simple fail on amigaos4 compiled with both clib2 and newlib. Through, one of many tests works for clib2, but not all. So, there is test case:

#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <cstring>

template<typename T>
bool test(int x, const char *fmt)
{
    
char buf_1[20] = {0};
    
snprintf(buf_1sizeof(buf_1), "%d"x);

    const 
T y x;
    
char buf_2[20] = {0};
    
snprintf(buf_2sizeof(buf_2), fmtx);

    const 
bool result = (strcmp(buf_1buf_2) == 0);
    if (
result)
        
fprintf(stderr"Ok (%s)n"fmt);
    else
        
fprintf(stderr"Error (%s) "%s" != "%s"n"fmtbuf_1buf_2);

    return 
result;
}

int main(int argccharargv[])
{
    
// https://en.cppreference.com/w/cpp/types/integer

    
test <uintptr_t>      (1"%" PRIuPTR);
    
test <uint_least64_t> (1"%" PRIuLEAST64);
    
test <uint_fast64_t>  (1"%" PRIuFAST64);
    
test <uint64_t>       (1"%" PRIu64);

    
test <intptr_t>       (1"%" PRIdPTR);
    
test <int_least64_t>  (1"%" PRIdLEAST64);
    
test <int_fast64_t>   (1"%" PRIdFAST64);
    
test <int64_t>        (1"%" PRId64);

    return 
0;
}


Now, compile it like this for newlib:

ppc-amigaos-g++ test-priuptr.cpp -o test-priuptr2_newlib

And like this for clib2:

ppc-amigaos-g++ -mcrt=clib2 test-priuptr.cpp -o test-priuptr2_newlib.

That what we have in output:

Newlib:

Quote:

9/0.Work:a> test-priuptr_newlib
Error (%llu) "1" != "160630978006482943"
Error (%llu) "1" != "160630978006482943"
Error (%llu) "1" != "160630978006482943"
Error (%llu) "1" != "160630978006482943"
Error (%lld) "1" != "160630978006482943"
Error (%lld) "1" != "160630978006482943"
Error (%lld) "1" != "160630978006482943"
Error (%lld) "1" != "160630978006482943"


Then, if i build the same test case with clib2, then:

Quote:

9/0.Work:a> test-priuptr_clib2
Ok (%lu)
Error (%llu) "1" != "4294967296"
Error (%llu) "1" != "4294967296"
Error (%llu) "1" != "4294967296"
Ok (%ld)
Error (%lld) "1" != "4294967296"
Error (%lld) "1" != "4294967296"
Error (%lld) "1" != "4294967296"



While if i compile for example for x86 then it:

Quote:

$ ./test-priuptr_x86.exe
Ok (%lu)
Ok (%lu)
Ok (%lu)
Ok (%lu)
Ok (%ld)
Ok (%ld)
Ok (%ld)
Ok (%ld)


Question is : WTF ?:) For clib2 only uintptr_t + PRIuPTR and uintptr_t + PRIdPTR works, while all others fail, and for newlib all fails.

Have anyone any explaining of this?


Edited by kas1e on 2020/2/6 5:59:25
_________________
Join us to improve dopus5!
zerohero's mirror of os4/os3 crosscompiler suites
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Home away from home
Joined:
2007/1/26 21:48
From New Zealand
Posts: 2223
@kas1e

Your test code has a problem where "int x" is 32-bit, but %llu/%lld needs a 64-bit value. The code might happen to work correctly on little-endian machines, provided that the next 32-bit value in memory happens to be 0. On big-endian machines like ours you're guaranteed to get a big number...

You should replace "int x" with "T x". T gets replaced with the template parameter (e.g., uintptr_t, uint64_t). Then the code should work.

%lu & %ld are for 32-bit values, which is why some clib2 tests are passing. Your results suggest that PRIuPTR is 32-bit for clib2 but 64-bit with newlib for some reason.

Hans

_________________
http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Home away from home
Joined:
2007/9/11 11:31
From Russia
Posts: 5882
@HAns
Quote:

You should replace "int x" with "T x". T gets replaced with the template parameter (e.g., uintptr_t, uint64_t). Then the code should work.


Nope, same error. Output start to be a bit different for newlib, but still errors of same kind

_________________
Join us to improve dopus5!
zerohero's mirror of os4/os3 crosscompiler suites
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Just can't stay away
Joined:
2006/11/30 11:30
From Finland
Posts: 1707
@kas1e

As far as I understand the newlib inttypes.h header file that was included with the SDK was an internal newlib header that should only be used for building newlib itself. When I encountered and reported this problem a few years back I was told to either remove the file or make a new one with the correct values.

I added a fixed version of the inttypes.h header to be used instead, in newlib V53.49 but since the latest public SDK is much older it still has the broken header file.

If your trying to port a linux program you could try to look for a HAVE_INTTYPES_H define and disable it (what I did for dvdauthor IIRC) or you could edit the inttypes.h header to replace the macros with correct definitions.

   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Just can't stay away
Joined:
2006/11/30 11:30
From Finland
Posts: 1707
@kas1e

Quote:

snprintf(buf_2, sizeof(buf_2), fmt, x);


The above line is wrong since x is always an int but the format string expects type T.

I'm not very experienced with C++ and templates but I think you should be able to fix it by casting it like so:

snprintf(buf_2, sizeof(buf_2), fmt, (T)x);

   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Home away from home
Joined:
2007/1/26 21:48
From New Zealand
Posts: 2223
@salass00

Quote:
snprintf(buf_2, sizeof(buf_2), fmt, (T)x);

That's correct. My suggestion would screw up the %d snprintf() above. Your modification will ensure that the input value is the correct type.

@kas1e
Try salass00's suggestion. If it still isn't working, then check what sizeof() says it the size of each of the types you're testing. Sizeof() should report 4 for 32-bit types, and 8 for the 64-bit ones.

Hans

_________________
http://hdrlab.org.nz/ - Amiga OS 4 projects, programming articles and more.
https://keasigmadelta.com/ - more of my work
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Not too shy to talk
Joined:
2015/6/11 8:51
From Cologne
Posts: 303
@kas1e
Forget all the stuff from above (edit: well, not all, I overlooked Salass' newlib inttypes.h issue). There simply is a little typo in your code:

const T y = x;
char buf_2[20] = {0};
snprintf(buf_2, sizeof(buf_2), fmt, x);

You see, you never use y...
That's how it should be:

const T y = x;
char buf_2[20] = {0};
snprintf(buf_2, sizeof(buf_2), fmt, y);

Salass' cast (T)x would do too, of course, but the true problem here is the x/y typo. And in C++ you'd actually prefer to write static_cast<T>(x) instead of (T)x, but well.


Edited by Daytona675x on 2020/2/6 13:20:33
Edited by Daytona675x on 2020/2/6 17:03:58
_________________
[Facebook] [YouTube Channel]
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Home away from home
Joined:
2007/9/11 11:31
From Russia
Posts: 5882
@All
Thanks all for help ! Yeah, there was a typo indeed. With that typo fixed all the clib2 tests passes fine, but newlib's ones fail on PRIuPTR and on PRIdPTR. Once i replaced inttypes.h from latest public SDK on one from latest beta of newlib as Salas00 says: all tests passes.

Phew! Thanks!

_________________
Join us to improve dopus5!
zerohero's mirror of os4/os3 crosscompiler suites
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Supreme Council
Joined:
2006/11/19 18:16
From London, England
Posts: 1311
And I think the moral of the story here is "Don't take code from other platforms as being bug free and great examples of talented coders".

:)

Simon

_________________
Comments made in any post are personal opinion, and are in no-way representative of any commercial entity unless specifically stated as such.
----
http://codebench.co.uk
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Just can't stay away
Joined:
2009/5/1 17:57
From Czech Republic
Posts: 1102
@Rigo

Quote:
"Don't take code from other platforms as being bug free and great examples of talented coders"


Exactly. Just a few days ago I ported a piece of Linux code that allowed writing 200 bytes into a 140-byte buffer. When I pointed that out, the author just said, "Oops..." )

_________________
Smoke me a kipper, I'll be back for breakfast!

AmigaOne X5000 @ 2GHz / 4GB RAM / Radeon RX 560 / ESI Juli@ / AmigaOS 4.1 Final Edition
SAM440ep-flex @ 667MHz / 1GB RAM / Radeon 9250 / AmigaOS 4.1 Final Edition
   Report Go to top

Re: c++11 : PRIu.... and PRId... all broken for both clib2 and newlib ?
Home away from home
Joined:
2007/9/11 11:31
From Russia
Posts: 5882
@Rigo,Trixie

Well, it was just a fast written test case, to check if we have issues in newlib. So, once the test case was fixed it indeed points out us on newlib's issue, which was fixed in a beta of newlib.

If newlib didn't have that bug in the first place, there weren't needs for test-example, as we create it only when start to have issues related to it.

I mean it's wasn't code from the real-life app, its just test-case which was written because some bigger program give us related bugs, and so we made a test case to find out the real bug, and we find it in newlib, just lucky it was already fixed in beta by Salas00.

And moral there not only that endianes matter and programmers less and less care about, but that our official libc newlib have issues from time to time :)

_________________
Join us to improve dopus5!
zerohero's mirror of os4/os3 crosscompiler suites
   Report Go to top





[Advanced Search]


Powered by XOOPS 2.0 © 2001-2016 The XOOPS Project