I'm using Microsoft VisualStudio 6

I need to concatenate 2 strings at compile time, to create a new string.

I want to do something like this




#define TableName "main"

char SelectStr[] = @CatStr("SELECT * FROM ", main, "WHERE id = ?")


This is mixed c++ and asm code
I need something like CatStr macro, or the dot operator used in php or VisualBasic to concatenate string

Thanks
Posted on 2005-01-13 12:09:17 by greenant
greenant, there's various ways of doing it. If you can stand a bit of runtime and executable overhead, I would advise you to look at std::string, since it's a lot safer than the regular ASCIZ strings (buffer overflows etc), and can grow as needed. If this is unacceptable, #include <string.h> , and use the string functions there. Be very careful though, the functions are inherently unsafe; if you must use str* functions, be sure to use the 'n' ones - like 'strncpy' instead of 'strcpy'.

If you don't have a C library reference, have a look at dinkumware - http://www.dinkumware.com/manuals/reader.aspx?b=c/&h=string.html . The C++ std::string is documented at http://www.dinkumware.com/manuals/reader.aspx?b=p/&h=string2.html .
Posted on 2005-01-13 12:22:00 by f0dder
greenant, there's various ways of doing it. If you can stand a bit of runtime and executable overhead, I would advise you to look at std::string, since it's a lot safer than the regular ASCIZ strings (buffer overflows etc), and can grow as needed. If this is unacceptable, #include <string.h> , and use the string functions there. Be very careful though, the functions are inherently unsafe; if you must use str* functions, be sure to use the 'n' ones - like 'strncpy' instead of 'strcpy'.

If you don't have a C library reference, have a look at dinkumware - http://www.dinkumware.com/manuals/reader.aspx?b=c/&h=string.html . The C++ std::string is documented at http://www.dinkumware.com/manuals/reader.aspx?b=p/&h=string2.html .


I use strcpy() in my C code, I'm just wondering how strncpy() would be safer than the regular function, because I thought there was no way strcpy would crash the program unless you passed a bogus pointer to it.
Posted on 2005-01-13 13:01:07 by x86asm
Consider this example:


#include <string.h>
int main(int argc, char* argv[])
{
char buf[16];
strcpy(buf, argv[1]);
}


...what happens if you pass a commandline of more than 16 chars? (Actually, more than 15, because of NUL termination). After answering the question, realize that the string functions without output length parameter should be done away with.
Posted on 2005-01-13 13:24:15 by f0dder
Hi greenant,

Using inline asm, you can code your own fast string concatenation function.
Posted on 2005-01-13 13:57:14 by Vortex
Be aware that strncpy - unlike strcpy - pads the rest of the destination buffer with 0. I once had big troubles because I forgot this little detail.
Posted on 2005-01-13 14:04:16 by japheth
Vortex, most compilers support "intrinsic functions". This means that for example strcpy (dunno about strncpy) will generate direct inline assembly - basically setup code and rep movsd.

Hm japheth, what kind of trouble has the zero-padding caused you?
Posted on 2005-01-13 14:16:05 by f0dder
guess :-D! ("of course" a buffer overflow (by 1 byte) due to an incorrect assumption about the max length of the destination buffer.)
Posted on 2005-01-13 14:33:48 by japheth
Thanks for the many reply but I need to concatenathe the strings at COMPILE TIME and not at RUN TIME
Posted on 2005-01-13 14:43:33 by greenant
Aaah, japheth, the famous off-by-one bugs :)

greenant, try "string1" ## definedstring ## "string2" ?

Hrm, unfortunately that only works in with other #defines - bummer. I thought there was a way to do this at arbitrary source locations, but I'm probably wrong.
Posted on 2005-01-13 14:45:20 by f0dder
What about the "db" cmd? :-D



TableName equ <"main">
SelectStr db "SELECT * FROM ", TableName, " WHERE id = ?",0
Posted on 2005-01-13 15:27:26 by japheth
I'm programming in C++ not in asm.
Why is more difficoult c++ than asm????? :(
Posted on 2005-01-13 15:49:33 by greenant


#include <stdio.h>

#define lala "blargh!"

int main(int argc, char *argv[])
{
printf(lala "nazg?l" lala "nnn\n");

return 0;
}
Posted on 2005-01-13 16:07:28 by f0dder
f0dder,

A good optimized asm strcpy algo is faster than rep movsd. :)
Posted on 2005-01-14 04:52:53 by Vortex
Vortex, I'd say it depends on the string lengths you are dealing with. Most strings shuffled around in C/C++ applications are rather short, so it might end up being slower if you use a super-optimized unrolled MMX algorithm. For generic str* replacements, I guess you should optimize for strings <100 chars, and probably even a bit less than that. REP MOVSD does pretty well there :)

Of course it can be advantagous with some of the "brutal" string routines, but you should consider which routines you use where, and why.
Posted on 2005-01-14 07:22:18 by f0dder
fodder,

No need for MMX, Hutch's szcopy algo should do the job:


; ?????????????????????????????????????????????????????????????????????????

.486 ; force 32 bit code
.model flat, stdcall ; memory model & calling convention
option casemap :none ; case sensitive

szCopy PROTO :DWORD,:DWORD

.code

; ?????????????????????????????????????????????????????????????????????????

align 4

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

comment * -- ---------------------------------------------
copied length minus terminator is returned in EAX
----------------------------------------------- *
align 16

szCopy proc src:DWORD,dst:DWORD

push ebp

mov edx, [esp+8]
mov ebp, [esp+12]
xor ecx, ecx ; ensure no previous content in ECX
mov eax, -1

@@:
add eax, 1
mov cl, [edx+eax]
mov [ebp+eax], cl
test cl, cl
jnz @B

pop ebp

ret 8

szCopy endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef

; ?????????????????????????????????????????????????????????????????????????

end
Posted on 2005-01-14 11:51:44 by Vortex