porting code to fb 1.04/x64

General FreeBASIC programming questions.
adele
Posts: 47
Joined: Jun 13, 2015 19:33

porting code to fb 1.04/x64

Postby adele » Dec 19, 2015 10:09

Hello,

I`m trying to port some of my code to fb/x64. The first issue I met was that the RTL function printf raised some warnings:

Code: Select all

C:\prg\fbc\fbc  -R -s console "coll.bas"
=== compiling coll
coll.bas
========================

coll.c: In function '_Z4DUMPPvu7INTEGER':
coll.c:2062:18: warning: format '%i' expects argument of type 'int', but argument 3 has type 'int64 {aka long long int}' [-Wformat=]
  printf( (uint8*)"Dumping %s Len=%i\x0D\x0A", *(uint8**)&TMP$360$1, THELEN$1 );
               ^


I actually relied on the FB manual`s hint that "integer" is 32 bit in FB32 and 64 bits in FB64, but the C-Compiler obviously still thinks that a FB integer is 4 Bytes long (=Type "LongInt" or "Long")
In the GNU doc of GCC/fprintf I found that there is a placeholder %q for qword==8 Bytes integer. As I don`t want to mess around with #if`s and #elseif`s a.s.o. just to compile the same code in FB32/FB64, I tried to write some kind of a "printf lite" in pure FreeBASIC, but I found out that the va_arg()-functions are not accepted the way I use them with FB32:

Code: Select all

C:\fbc\fbc  -R -s console "fprnt.bas"
fprnt.bas(250) error 285: Unsupported statement in -gen gcc mode in 'Dim As Any Ptr arg = va_first()'
fprnt.bas(283) error 285: Unsupported statement in -gen gcc mode, found 'va_arg' in 'result+= Str(va_arg(arg, Integer))'
fprnt.bas(287) error 285: Unsupported statement in -gen gcc mode, found 'va_next' in 'arg = va_next(arg, Integer)'
fprnt.bas(291) error 285: Unsupported statement in -gen gcc mode, found 'va_arg' in 'result+= Str(va_arg(arg, LongInt))'
fprnt.bas(292) error 285: Unsupported statement in -gen gcc mode, found 'va_next' in 'arg = va_next(arg, LongInt)'
fprnt.bas(298) error 285: Unsupported statement in -gen gcc mode, found 'va_arg' in 'result+= Str(va_arg(arg, Double))'
fprnt.bas(299) error 285: Unsupported statement in -gen gcc mode, found 'va_next' in 'arg = va_next(arg, Double)'
fprnt.bas(301) error 285: Unsupported statement in -gen gcc mode, found 'va_arg' in 'result+= Str(va_arg(arg, Double))'
fprnt.bas(302) error 285: Unsupported statement in -gen gcc mode, found 'va_next' in 'arg = va_next(arg, Double)'
fprnt.bas(308) error 285: Unsupported statement in -gen gcc mode, found 'va_arg' in 'result+= *va_arg(arg, ZString Ptr)'
fprnt.bas(308) error 132: Too many errors, exiting

Build error(s)


Just in case I forgot to mention:
Everything works fine w/o Errors or warnings using FB/32.

So my questions:
Is there any way to compile the same Code (using printf) in both FB32/64, without conditional compiling, or, preferably, can I convince the compiler to accept the va_args() statements, which are AFAIK needed by (almost?) all of the cdecl() functions?

My FB64 Compiler says it is

FreeBASIC Compiler - Version 1.04.0 (10-01-2015), built for win64 (64bit)
Copyright (C) 2004-2015 The FreeBASIC development team.
standalone

Thank you a lot.

Adele
dkl
Site Admin
Posts: 3212
Joined: Jul 28, 2005 14:45
Location: Germany

Re: porting code to fb 1.04/x64

Postby dkl » Dec 19, 2015 12:19

Hi,

printf is a C function (C runtime library), that of course doesn't know about FreeBASIC at all. printf %i refers to C's int type, that is always 32bit with gcc on Linux/Windows (corresponding to FB's Long). I'm not sure what the best solution is, but maybe like this:

Code: Select all

#include "crt/stdio.bi"

dim int32 as long = 32
dim int32or64 as integer = 3264

'' %i prints C's int, that's 32bit
'' and gcc shows a warning if you pass an int64 or something
printf(!"%i\n", int32)

'' %zd prints C's size_t, that's 32bit or 64bit like FB's Integer
'' but unfortunately gcc may still show a warning, because it may consider
'' size_t to be a different type than what fbc -gen gcc uses to implement Integer.
'printf(!"%zd\n", int32or64)

'' But what we can do is do declare a helper macro like C's inttypes.h
'' (unfortunately FB doesn't provide a crt/inttypes.bi out of the box currently)
#ifdef __FB_64BIT__
   '' fbc -gen gcc uses C's long long to implement FB's Integer, so let's use %lld
   '' (64bit decimal)
   #define PRId_INTEGER "lld"
#else
   '' fbc -gen gcc uses C's int to implement FB's Integer, so let's use %d
   '' (32bit decimal, same as %i for output)
   #define PRId_INTEGER "d"
#endif
printf("%" PRId_INTEGER !"\n", int32or64)


These compiler warnings about printf format specifiers are coming from gcc, when using fbc's C backend - otherwise, when using fbc's 32bit x86 ASM backend, such problems wouldn't even be found.

And as you noticed, fbc's C backend doesn't support va_first/va_arg/va_next statements, so it's not possible to implement var-arg functions in FB code compiled with for 64bit or ARM or (on x86) with -gen gcc. Unfortunately there's no work-around/alternative while using FB, for now... i.e. currently such functions have to be written in C, compiled with gcc, and can then be linked with the modules compiled with fbc, to create the final program.
adele
Posts: 47
Joined: Jun 13, 2015 19:33

Re: porting code to fb 1.04/x64

Postby adele » Dec 20, 2015 19:16

@dkl,

Thank you for the reply. That' s what I thought, too.
But: If s.th. like va_?? works with the C compiler (using C), how do they do that?

OK, my "workaround" is a very naive one: I put all this stuff into a lib, so I don't see the warnings anymore ;-)

adele
dkl
Site Admin
Posts: 3212
Joined: Jul 28, 2005 14:45
Location: Germany

Re: porting code to fb 1.04/x64

Postby dkl » Dec 20, 2015 19:23

Regarding FB's current va_* functions:
short explanation: viewtopic.php?p=206076#p206076
more details: viewtopic.php?p=201579#p201579

Return to “General”

Who is online

Users browsing this forum: No registered users and 9 guests