0

Is this conversion from jint* (32 bit signed) to uint32_t* valid? It works, but it seems to be a hack. Programming language is C.

JNIEXPORT jint JNICALL Java_foo_bar(JNIENV *env, jobject thisObj, jintArray inputDataJava){

/* Input data is signed */
jint * inputDataSigned = (*env)->GetIntArrayElements(env,inputDataJava,0);

/* Input data has been casted to unsigned. Is that valid? */
uint32_t * inputDataUnsigned = (uint32_t *) (*env)->GetIntArrayElements(env,inputDataJava,0);

}

Thanks in advance

ben
  • 207
  • 1
  • 10
  • Is this C or C++? Please decide. For C, this definitely *is* a hack you shouldn't do. (I think for C++ as well, but not absolutely sure...) Just access and convert the *value*. –  Jun 23 '17 at 06:09
  • It is C. Edited. Thanks. – ben Jun 23 '17 at 06:20
  • 1
    Would have been enough to remove the C++ tag then, I just did that. So if it's C, I can tell you for sure that accessing the value through a pointer of incompatible type is not allowed. Convert the value itself instead. –  Jun 23 '17 at 06:24
  • Thanks. But in the answer in that post https://stackoverflow.com/questions/5040920/converting-from-signed-char-to-unsigned-char-and-back-again it was done in the "hack" way... Last line ("or the C way:...") I don't care about the values. I work only with the bits... Cheers Ben – ben Jun 26 '17 at 11:57

1 Answers1

0

Is this conversion from jint* (32 bit signed) to uint32_t* valid?

In short, no. It is possible for an implementation to exist where such a cast would cause quite some undesirable behaviour.


It works, but it seems to be a hack.

Many undefined behaviours seem to work, at least initially, for one configuration... up until someone notices heartbleed or some other vulnerability which the undefined behaviour might seem to have caused, for example. Indeed, often people will overflow their arrays by a single byte, and their programs will continue to run...


There are very few types of pointers which have alignment requirements loose enough to point at any type. The only ones I know of from the C standard are the character pointer types (char *, signed char *, unsigned char *) and void *.

Complicating matters is that the standard knows nothing of this jint * nor any alignment requirements. I would not trust such code. Please see the relevant conversion section of the C standard to get an idea of what is acceptable: 6.3.2.3 Pointers quoted below for your convenience. As a programmer you'll generally want to steer clear of anything "undefined".

1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

2 For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.

3 An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.66) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

4 Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.

5 An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.67)

6 Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

7 A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned68) for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

8 A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced type, the behavior is undefined.

autistic
  • 1
  • 3
  • 35
  • 80