I'm working through Sheng Liang's "The JNI Programmer's Guide and
Specification", and am on chapter 3, working the "Prompt" example. I'm
working through all the examples using gcc on GNU/Linux and VC++ on MS
Windows. Here's the C code in Sheng's book:
#include <stdio.h>
#include "Prompt.h"
JNIEXPORT jstring JNICALL
Java_Prompt_getLine( JNIEnv *env, jobject obj, jstring prompt )
{
char buf[128];
const jbyte *str;
str = (*env)->GetStringUTFChars( env, prompt, NULL );
if ( str == NULL ) return NULL;
printf("%s", str);
(*env)->ReleaseStringUTFChars(env, prompt, str);
scanf("%s", buf);
return (*env)->NewStringUTF(env, buf);
}
When I compile this with gcc, I get the warnings:
Prompt.c: In function Java_Prompt_getLine() Prompt.c:16: warning: pointer
targets in assignment differ in signedness
Prompt.c:20: warning: pointer targets in passing argument 3 of
(*env)->ReleaseStringUTFChars() differ in signedness
The code to focus on here is:
const jbyte *str;
str = (*env)->GetStringUTFChars( env, prompt, NULL );
(*env)->ReleaseStringUTFChars(env, prompt, str);
Looking into jni.h:
const char* (JNICALL *GetStringUTFChars)
(JNIEnv *env, jstring str, jboolean *isCopy);
void (JNICALL *ReleaseStringUTFChars)
(JNIEnv *env, jstring str, const char* chars);
And from linux/jni_md.h:
typedef signed char jbyte;
Doing some Googling, it appears that the C standard allows char to be either
signed or unsigned by default. Using a small test program where I set a char
variable equal to 255, it appears that with gcc on GNU/Linux, a char by
default is signed.
So I don't see the problem here.
* GetStringUTRChars() returns a ptr to a signed char.
* The 3rd arg of ReleaseStringUTFChars() takes a ptr to a signed char.
* A jbyte is a signed char
So what exactly is gcc complaining about?
Thanks for reading down this far. :)
Pete
Gordon Beaton - 01 Jun 2006 20:35 GMT
> When I compile this with gcc, I get the warnings:
>
[quoted text clipped - 3 lines]
> Prompt.c:20: warning: pointer targets in passing argument 3 of
> (*env)->ReleaseStringUTFChars() differ in signedness
[...]
> * GetStringUTRChars() returns a ptr to a signed char.
> * The 3rd arg of ReleaseStringUTFChars() takes a ptr to a signed char.
> * A jbyte is a signed char
>
> So what exactly is gcc complaining about?
According to the gcc documentation, the type "char" is distinct from
both "signed char" and "unsigned char", even though its behaviour is
always identical to one of them.
Various alternative solutions are:
- declare your variables so the sign agrees
- don't use -pedantic if that's what you're doing
- turn off the specific warning with -Wno-pointer-sign
- use a cast
- ignore the warning
/gordon

Signature
[ do not email me copies of your followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Chris Uppal - 01 Jun 2006 20:40 GMT
> * GetStringUTRChars() returns a ptr to a signed char.
> * The 3rd arg of ReleaseStringUTFChars() takes a ptr to a signed char.
> * A jbyte is a signed char
>
> So what exactly is gcc complaining about?
I think it's probably about GNU's ultra precise (and legitimately so)
interpretation of what 'char' means in C (or C++). There are /three/ possible
signednesses for a char -- default (i.e. unspecified, which is what you get if
you have just 'char'), explicitly signed, and explicitly unsigned. GCC will
moan if you implicitly convert between any of the three.
Broadly speaking, in this context, the warnings can be ignored.
-- chris
Dale King - 02 Jun 2006 15:39 GMT
> I'm working through Sheng Liang's "The JNI Programmer's Guide and
> Specification", and am on chapter 3, working the "Prompt" example. I'm
> working through all the examples using gcc on GNU/Linux and VC++ on MS
> Windows. Here's the C code in Sheng's book:
[snip]
> The code to focus on here is:
>
[quoted text clipped - 10 lines]
>
> So what exactly is gcc complaining about?
Gordon and Chris explained why gcc is complaining, but the real problem
is that str was declared to be of type const jbyte *. It should be of
type const char * since that is the type for the functions.
If you download the examples from the web site
(http://java.sun.com/docs/books/jni/) you will see that they did in fact
make this correction.
So I would suggest relying on the downloadable example code which can be
updated instead of the text of the book, which can not readily be revised:

Signature
Dale King
Peter Jay Salzman - 02 Jun 2006 17:54 GMT
>> I'm working through Sheng Liang's "The JNI Programmer's Guide and
>> Specification", and am on chapter 3, working the "Prompt" example. I'm
[quoted text clipped - 28 lines]
> So I would suggest relying on the downloadable example code which can be
> updated instead of the text of the book, which can not readily be revised:
Thanks Gordon and Chris! And I learned something new about C to boot! I had
no idea that char was distinct from signed char. I'm really thankful for
your responses.
Also, Dale, thanks for the tip about the code change. I'm still a Java
newbie, but it seems like the prototypes for GetStringUTFChars() and
ReleaseStringUTFChars are broken -- they should probably be using "const
signed char *", rather than "const char *".
I've verified that on Linux and Windows with Sun Java, a jbyte is typedefed
from a "signed char".
Thanks all!
Pete
Dale King - 02 Jun 2006 22:25 GMT
>> So I would suggest relying on the downloadable example code which can be
>> updated instead of the text of the book, which can not readily be revised:
[quoted text clipped - 3 lines]
> ReleaseStringUTFChars are broken -- they should probably be using "const
> signed char *", rather than "const char *".
I don't think signed or unsigned is more correct than another. I think
char is a better choice than signed char because the data is essentially
text for any characters that are in ASCII. It is likely that a user of
the UTF string will want to process it as text including possibly
printing it out. In that case there is benefit to it being char as there
will be API's that expect char.
The one thing that they definitely did get wrong (and I just filed a bug
report on) is the JNINativeMethod structure that is used as part of
RegisterNatives has 2 pointers to utf strings, but doesn't declare them
as pointers to const, so I have to do a const_cast in C++.

Signature
Dale King