JNI: Signedness with GetStringUTFChars() and ReleaseStringUTFChars()

Discussion in 'Java' started by Peter, Jun 1, 2006.

  1. Peter

    Peter Guest

    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
    Peter, Jun 1, 2006
    #1
    1. Advertising

  2. On 1 Jun 2006 20:31:40 +0200, Peter wrote:
    > 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


    [...]

    > * 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

    --
    [ 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
    Gordon Beaton, Jun 1, 2006
    #2
    1. Advertising

  3. Peter

    Chris Uppal Guest

    Re: Signedness with GetStringUTFChars() and ReleaseStringUTFChars()

    Peter wrote:

    > * 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
    Chris Uppal, Jun 1, 2006
    #3
  4. Peter

    Dale King Guest

    Peter wrote:
    > 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:
    >
    > const jbyte *str;
    > str = (*env)->GetStringUTFChars( env, prompt, NULL );
    >
    > Looking into jni.h:
    >
    > const char* (JNICALL *GetStringUTFChars)
    > (JNIEnv *env, jstring str, jboolean *isCopy);
    >
    > void (JNICALL *ReleaseStringUTFChars)
    > (JNIEnv *env, jstring str, const char* chars);
    >
    > 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:


    --
    Dale King
    Dale King, Jun 2, 2006
    #4
  5. Dale King <"DaleWKing [at]gmail [dot] com"> wrote:
    > Peter wrote:
    >> 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:
    >>
    >> const jbyte *str;
    >> str = (*env)->GetStringUTFChars( env, prompt, NULL );
    >>
    >> Looking into jni.h:
    >>
    >> const char* (JNICALL *GetStringUTFChars)
    >> (JNIEnv *env, jstring str, jboolean *isCopy);
    >>
    >> void (JNICALL *ReleaseStringUTFChars)
    >> (JNIEnv *env, jstring str, const char* chars);
    > >
    >> 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:


    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
    Peter Jay Salzman, Jun 2, 2006
    #5
  6. Peter

    Dale King Guest

    Peter Jay Salzman wrote:
    > Dale King <"DaleWKing [at]gmail [dot] com"> wrote:
    >>
    >> 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:

    >
    > 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 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++.

    --
    Dale King
    Dale King, Jun 2, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. qazmlp
    Replies:
    6
    Views:
    2,502
    Qu├ębec
    Jul 31, 2004
  2. Naresh Agarwal
    Replies:
    3
    Views:
    10,409
    Gordon Beaton
    Jul 1, 2005
  3. Frederick Gotham

    Bitshifting independant of signedness

    Frederick Gotham, Aug 24, 2006, in forum: C Programming
    Replies:
    4
    Views:
    335
    Michael Mair
    Aug 25, 2006
  4. Marc
    Replies:
    0
    Views:
    353
  5. Pietro Cerutti

    char * signedness

    Pietro Cerutti, Jul 5, 2007, in forum: C Programming
    Replies:
    17
    Views:
    628
Loading...

Share This Page