I think tim_milliken had the same problem. he wrote in the message 5: "I made a compltely new project and that is the only thing I did, and it did not work. I sometime step into sprintf and notice that the format that gets passed in is messed up."
One problem with the (s)printf type of functions in C is that the open argument part is completely untyped. The compiler is not knowing what you should pass on the open arguments, therefore it will just pass through whatever you put there, that's completely independent of the expected arguments. Your problem now is that the type of the actual argument (stH) does not match what the compiler expects for the %s part. Out of the box (as specified by the ANSI standard), %s expects a "(const)char*". If you changed the ANSI library by modifying LIBDEF_StringPtr to be a "(const)char*__far", then it now expects that type.
I do recommend to explicitely cast every single argument to an open argument function like (s)printf, so in your case: > sprintf(stO, "%s", (LIBDEF_StringPtr)stH);
That will make sure that sprintf gets what it expects. If LIBDEF_StringPtr is a far pointer then that will fix your issue. Note that I do recommend that cast independetly of the far/near pointer story, I do the same for %d -> (int), %lx -> (unsigned long), ... Basically this way the compiler will at least adapt the type as much as possible, well if the type does not fit, that just cuts, but that's far better than to put a part of the content into the next arguments...
BTW: Other problems with sprintf: - no overflow checking in the output buffer - you get always all features of sprintf even if you just use 5% of them (and you pay with code space for all the features) - can cause crashers if open arguments are incorrect - correctness affected by the complex C rules for type propagation - bugs are found at runtime, if at all. Not at compile time. - many details to know about all the formatting possibilities and the effects of all the flags. - slow (relatively)
The only good thing I know about sprinf, calling sprintf is rather dense, both in code size and in source code length.
Also use strcpy(stO, stH) to copy strings, not sprintf(stO, "%s", (LIBDEF_StringPtr)stH); :smileyhappy:.
Well, I don't see any string here. Anyway, the way the CONST_USR section is used in the pragma, it must be allocated non banked in the banked memory model. Therefore what is the address of tVd in our map file? Also, I wonder how you did actually "put string in banked memory", what did you change? Make sure to explicitly allocate all your custom, explicitly banked, CONST sections into banked area. Don't place DEFAULT_ROM or ROM_VAR banked as that would cause sections to get banked allocated which are not prepared for that, like this CONST_USR section.
I was under the obviously wrong impression that you intended to allocate strings only (say string literals) and not all constants banked. OK, so the problem is the #pragma you are using. If you allocate variables/constants not the default way the memory model dictates, then the pragma has to mention that too. More specific, your pragma should be
#pragma CONST_SEG __PPAGE_SEG CONST_USR
just as the STRING_SEG is qualified in the FAQ. It's the same thing for the CONST_SEG too.