Hi,
I need to refer to fixed width fields in strings read from file lines. Is it possible to pass a c function the char* plus an offset?
I assume that s[0..4] creates a new string and I want to avoid that.
Example:
"abcdefg" + 4
would refer to "efg"
Have fun shooting your foot :)
proc main() =
var x: cstring="abcdefg"
var y: cstring=cast[cstring](cast[ByteAddress](addr(x[0])) +% 4)
echo x
echo y
main()
UPDATE: Really meant ByteAddress and added jehans unsigned integer hint.
Hi @OderWat: Out of curiosity, why did you use BiggestInt rather than int in the cast? int is defined to be the same size as a pointer, so surely that would be a better match? In fact, there's even a type ByteAddress ("the signed integer type that should be used for converting pointers to integer addresses for readability") that's typedef-ed to int. (I'm assuming that the cstring variable is a pointer.)
Hi @Jehan: Thanks for that tip about +% in pointer arithmetic!
I was going to ask: "Why would the sign wrap?" => Realisation: Of course, because the pointer is in an unsigned space, a very large pointer value could wrap from a positive int to a negative int.
Then I was going to ask: "So why don't we just cast to uint rather than int?" Which of course, led me to the usual explanations:
Relatedly, I've been meaning to ask about module unsigned: The module itself is marked as deprecated, and the documentation for 'unsigned' is gone, but there was never any announcement on the Nim news page.
During that previous search about unsigned integers, I found an answer to my question: Module 'unsigned' was deprecated on the 6th of March, this year; but I guess that wasn't merged across to master until 2nd of July.
Thanks everybody,
At last, I've simplified a bit the expression to:
cast[cstring](addr(cs[offset]))
and included this in a template that binds to an sqlite statement:
template bind_text_param(st:Pstmt, npar:int, cs:cstring, offset:cint, length:cint, mode=SQLITE_STATIC) =
assert bind_text(
st,
npar,
cast[cstring](addr(cs[offset])),
length,
mode
) == SQLITE_OK
The reason for the code is to import some really big files (more than 20gb) in an sqlite db. This makes a difference of -10% over the version with string[start..end]