Integer concenation with macro

New to FreeBASIC? Post your questions here.
Post Reply
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Integer concenation with macro

Post by nimdays »

Hello,

How to concenate integer correctly with macro ?
I must call it twice here because i can't add something after ","(error)

Code: Select all

#define concat(a,b,c) a##b##c
dim as integer a=10,b=20,c=30,d
d = a concat(*100+,,)b
d = d concat(*100+,,)c
?d  '102030
sleep
Thanks.
integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Re: Integer concenation with macro

Post by integer »

nimdays wrote:Hello,

How to concenate integer correctly with macro ?
I must call it twice here because i can't add something after ","(error)

Code: Select all

#define concat(a,b,c) a##b##c
dim as integer a=10,b=20,c=30,d
d = a concat(*100+,,)b
d = d concat(*100+,,)c
?d  '102030
sleep
Thanks.
perhaps this:

Code: Select all

#define concat(a,b,c)  (a*100+b)*100+c
'' OR 
#macro concatenate(a,b,c)
  a*10000 + b*100 + c
#endmacro
''-------------

dim as integer a=10, b=20, c=30, d
d = concat(a,b,c)
print d;"  s/b '102030'"
print
dim as integer x=101,  y=22,  z=3
print concat(x,y,z);" s/b  '1012203'"
print
d = concatenate(a,y,z+1)		''notice the addition inside the macro
print d
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Integer concenation with macro

Post by fxm »

To avoid unexpected precedence order of operators, put parentheses systematically inside macro body (even where this is not absolutely necessary) is a good habit.
From the above example:

Code: Select all

#define concat(a,b,c)  (((a)*100+(b))*100+(c))
'' OR
#macro concatenate(a,b,c)
  ( (a)*10000 + (b)*100 + (c) )
#endmacro
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Integer concenation with macro

Post by nimdays »

integer wrote:
perhaps this:

Code: Select all

#define concat(a,b,c)  (a*100+b)*100+c
'' OR 
#macro concatenate(a,b,c)
  a*10000 + b*100 + c
#endmacro
''-------------

dim as integer a=10, b=20, c=30, d
d = concat(a,b,c)
print d;"  s/b '102030'"
print
dim as integer x=101,  y=22,  z=3
print concat(x,y,z);" s/b  '1012203'"
print
d = concatenate(a,y,z+1)		''notice the addition inside the macro
print d
Thank you both.
fxm wrote:To avoid unexpected precedence order of operators, put parentheses systematically inside macro body (even where this is not absolutely necessary) is a good habit.
From the above example:

Code: Select all

#define concat(a,b,c)  (((a)*100+(b))*100+(c))
'' OR
#macro concatenate(a,b,c)
  ( (a)*10000 + (b)*100 + (c) )
#endmacro
integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Re: Integer concenation with macro

Post by integer »

fxm wrote:To avoid unexpected precedence order of operators, put parentheses systematically inside macro body (even where this is not absolutely necessary) is a good habit.
...
Thank you.
That might explain some problems previously experienced with macros.
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Integer concenation with macro

Post by fxm »

integer wrote:That might explain some problems previously experienced with macros.
There is already a "WARNING" at description end of #DEFINE page in documentation:
WARNING: When the macro body contains an expression with one operator at least, it may be mandatory to have to surround some terms (parameters, whole body) by parentheses in order to not undergo an unwanted precedence change of operators.
From still the same example, I put in red the mandatory parentheses added because it's a macro and in green the added but optional parentheses:
#define concat(a,b,c) _
( ( ( a ) * 100 + ( b ) ) * 100 + ( c ) )
'' OR
#macro concatenate(a,b,c)
( ( a ) * 10000 + ( b ) * 100 + ( c ) )
#endmacro
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Integer concenation with macro

Post by dodicat »

The brackets inside a macro are important.
I had just about given up with this macro to simulate memcpy from crt.bi
As a last resort, before binning everything, I bracketed off the macro.
And then, it seemed to work:

Code: Select all



#include "crt.bi"


#macro memcpyFB(dest,src,size)
scope
   var sz=(size)/sizeof(*(src))
    for n as long=0 to sz-1
        (dest)[n]=(src)[n]
    next
end scope
#endmacro


'udt test
type udt
    as integer i
    as string s
    as long a(45)
end type

dim as udt x(123),y(123),z(123)
x(25).i=13
x(25).s="Hello"
x(25).a(13)=78

memcpyFB(@y(0),@x(0),(ubound(x)-lbound(x)+1)*sizeof(x))

print y(25).i,y(25).s,y(25).a(13),"freebasic"


memcpy(@z(0),@x(0),(ubound(x)-lbound(x)+1)*sizeof(x))

print z(25).i,z(25).s,z(25).a(13),"c runtime"
'===============
'array test
dim as string a(3,8),b(3,8),c(3,8)

dim as long size=((ubound(a,1)-lbound(a,1)+1)*(ubound(a,2)-lbound(a,2)+1)*sizeof(string))

a(3,8)="FreeBASIC"
memcpyFB(@b(0,0),@a(0,0),size)
print b(3,8)

a(3,8)="C runtime"
memcpy(@c(0,0),@a(0,0),size)
print c(3,8)
sleep

 
fxm
Moderator
Posts: 12110
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Integer concenation with macro

Post by fxm »

Indeed, in your above macro example, but without parentheses:
@variable[n]
would be parsed as:
@(variable[n])
due to the operators precedence between '[]' and '@',

but the wanted expression is:
(@variable)[n]
Post Reply