Hello , I recompiled the applications related to GTK GINTRO. I encountered a problem that I did not have before in 1.4.8
I was forced to cast ex: window.setTitle (cstring (widget.getWindowTitle ()))
else: Warning: implicit conversion to 'cstring' from a non-const location: getWindowTitle (widget); this will become a compile time error in the future [CStringConv]
otherwise all my recompile applications are OK
ps it is not due to GINTRO not to the passing of parameter a of the C of string a const string
No, there is an implicit conversion when passing a string to a cstring. But it seems that nim 1.6.0 has introduced a check to make sure that the argument cannot be modified.
This triggers the warning:
proc p(s: cstring) =
discard
var s = "abc"
p(s)
and this doesn’t trigger the warning:
proc p(s: cstring) =
discard
let s = "abc"
p(s)
When the argument is the result of a function call which returns a value (not a var), I think that the warning is incorrect.
Warning: implicit conversion to 'cstring'
We had a discussion and an Nim issue since August for that:
https://github.com/StefanSalewski/gintro/issues/162
https://github.com/nim-lang/Nim/issues/18698
It is indeed an ugly regression, as cstrings are fine for GTK. See the issues for detailed discussion.
I do switch it off generally with
{.warning[CStringConv]: off.}
But I can not put that in the gtk modules as then they would not compile with Nim < 1.5. There may be conditional code possible, but then I would have to install older compiler version just to check that.
When this will really become an error, then I can only hope that there will be a matching
{.error[CStringConv]: off.}
is cstring (variable) the correct solution ???
I read issue thank
resume my applications does not cost me dear
with autumn the motorcycle turns less;)
is cstring (variable)
Of course not. Just pass the string to the gtk functions as before. Have you ever compiled Linux C libs? The C compilers display generally hundred of warnings, and no one cares. Even when you compile gcc, clang or firefox. Everybody uses that software, no one cares for the warnings.
We get the warnings for gtk, because we call the gtk functions by use of trampoline functions, and Araq seems to fear that we may do stupid things with the cstring in that trampoline function. Of course we do not, we just pass the cstring to the C lib. But all that had been discussed in the issues.
The implicit string->cstring conversions are against Nim's safety rules and they are a legacy. The workaround is to write cstring(x) and that will continue to work. If they occur too often so that they become annoying, this part of your wrapper seems rather poorly designed, sorry.
But if you a better idea of how to handle that, I'm listening. Also, it was you who closed the issue, not me.
poorly designed,
Nimrod had first class cstrings, for a good reason.
Of course we can change the string parameter type of the trampoline functions to Nim string. The disadvantage is that then we can not pass nil, only an empty string. But for some gtk functions empty string and nil generates a different behaviour. For current gintro we have a few hundred functions that accept nil as a valid cstring value. We could generate overloads for all these function, which is not really easy and would increase compile time. What we may do indeed is converting each empty Nim string to nil and then passing nil to the C library function. Indeed that should be OK for most cases, only the few cases where we would want to pass really an empty string would fail. I don't know for how many functions that would be the case. A disadvantage may be larger executable size, as passing a cstring to the trampoline function is passing only a pointer, while passing a Nim string is copying some more bytes. And we have to call the "empty Nim string to nil" converter proc for each parameter. So executable size should grow indeed.
But for some gtk functions empty string and nil generates a different behaviour. For current gintro we have a few hundred functions that accept nil as a valid cstring value.
These two sentences are not obviously related, how many out of these hundred functions that accept nil actually distinguish between nil and "" in a meaningful way?
To put into context, the motivating example for the warning is that the memory a cstring points to may become invalid.
the link shows it pretty clearly for the standard gc, here's a simple/contrived example that 'works' with --gc:arc
var s = "original"
s.setLen(1024*1024)
proc p(s:var string, c: cstring) =
s &= '.'
var tmp = "clobbered"
tmp.setLen(1024*1024)
echo c
p(s,s)
I recently had this warning in code that looked something like this:
proc foo(bar: cstring) {.importc, header: "foo.h".}
proc fooWrapper(baz: string) =
foo("~~$1~~" % baz)
I changed it to this to get rid of the warning:
proc foo(bar: cstring) {.importc, header: "foo.h".}
proc fooWrapper(baz: string) =
let bar = "~~$1~~" % baz
foo(bar.cstring)
What's the proper way to do it?