long type in solaris

S

silvia.fama

Hi!
I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

On windows machine it works well, on Solaris not. The windows and
solaris path into c language is the same.
I'd like to say also that real value works correctly also if they are
used in the same manner:
memcpy(string, (real *) value, len)

Is there a particular manner to use long values on solaris?
Or to use memcpy with long types?

Thank you very much, I hope to be clear.
 
C

Clark S. Cox III

Hi!
I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

I'm not sure what you hope to achieve by casting value to (long*),
you'll have to be more clear as to what your intentions actually are.
On windows machine it works well, on Solaris not. The windows and
solaris path into c language is the same.
I'd like to say also that real value works correctly also if they are
used in the same manner:
memcpy(string, (real *) value, len)

Is there a particular manner to use long values on solaris?
Or to use memcpy with long types?

memcpy doesn't care about types, it simply copies bytes.
 
N

Nick Keighley

I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
why?


memcpy(string, (long *) value, len)

if value is a long why do you cast it to a (long*)?

I'd probably code it like this:-

memcpy (string, &value, sizeof value);

this value will be then insert into a database.

On windows machine it works well, on Solaris not.

what does "not work well" mean?

The windows and
solaris path into c language is the same.
I'd like to say also that real value works correctly also if they are
used in the same manner:
memcpy(string, (real *) value, len)

?? "real" is not a C type I recognise.

Is there a particular manner to use long values on solaris?
Or to use memcpy with long types?

Thank you very much, I hope to be clear.

well no...

Its possible the bytes are arranged in a different order between
Windows and Solaris. A so called "endian" problem. You may
have to rearrage the bytes in the string before the write.

You need to explain what your problem is.


--
Nick Keighley

GOD IS REAL.
Unless a type declaration to the contrary is made.
(old FORTRAN joke)
 
C

Chris Dollin

Hi!
I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

This code is almost certainly wrong, but because you haven't
shown us any of the other declarations and uses it's hard
to say what, exactly, is wrong.

I say it's wrong because you have a cast `(long *) value`. Either
`value` is a pointer type (even though you imply that it's a long),
in which case you don't need the cast [1], or it isn't, in which
case you're handing a non-pointer to `memcpy`, BOOM.

I wonder if you meant `&value`? In which case, again, you don't
need the cast [1].

How many bytes are you copying? We don't know what `len` is.
One hopes that it's `sizeof(long)`. One also hopes that the
"string" location is long enough. One hopes that it has enough
space for the terminating 0. The code you show doesn't put the
terminating 0 in. Of course, maybe some unshown code does. Or
perhaps "string" isn't the right name for the variable.

How many bytes is the database expecting? What makes you think
that `len` is the right number, and what makes you think that a
`long` is exactly that wide? Because if a `long` is shorter
than that, you'll be copying rubbish; and if longer, you'll miss
out on some bytes, maybe the most relevant ones [2].
On windows machine it works well, on Solaris not.

What kind of ill working do you see?
The windows and solaris path into c language is the same.

"I don't know what that means" [3].

I suspect you're hitting an endianness / sizeof problem,
which because you didn't anticipate it may be a right
buxxer to fix.

[1] Assuming that you've remembered to #include <string.h>.

[2] EG if the `long` has the value `17`, the bytes holding the
`17` are the relevant ones.

[3] Bones.
 
R

Richard Bos

I'm using c language.

No kiddin'. And here I thought this was comp.lang.snobol.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

On windows machine it works well, on Solaris not. The windows and
solaris path into c language is the same.

Post real code, not unclear snippets. Cut your code to the smallest
compilable program which still exhibits your problem, then
copy-and-paste (do _not_ retype!) that. Otherwise, we are left guessing.
(E.g., I could guess that whatever stands in for "len" in your actual
code is correct for Windows, most likely by accident, but incorrect for
Solaris. But without real code, that remains a guess.)

Richard
 
P

p_cricket_guy

Hi!
I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

Please post your code. Otherwise, questions like these surface:
1. Is value a long type or a pointer to a long type?
2. Does string point to vlaid and enough memory?
3. What are you assigning to len? sizeof long, perhaps.
On windows machine it works well, on Solaris not. The windows and
solaris path into c language is the same.
I'd like to say also that real value works correctly also if they are
used in the same manner:
memcpy(string, (real *) value, len)

Is there a particular manner to use long values on solaris?
Or to use memcpy with long types?

I am sure somebody can help if you post a complete C program
that exhibits the problem.
 
J

Jens Thoms Toerring

I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)

If 'value' is a long int variable then this looks rather strange.
The second argument to memcpy() must be _pointer_, but here you
just cast the value to a pointer, so whatever the result of the
cast is (not necessarily something useful), this will be taken to
be an address that gets dereferenced from within memcpy(). Even
if this by accident shouldn't segfault, the value itself will de-
finitely not be copyied to 'string', just the content of the memory
it's (accidentally). pointing to. But even if you change that to

memcpy(string, &value, len)

what ends up in string isn't going to be a textual representation
of what's stored in 'value' but some binary data. I don't know
if that's what you want (but since you don't tell what 'string'
is and how it's going to be used it's hard to guess).

And then the question is what 'len' is supposed to be. You
don't show what type and value it has, so nobody can tell
if you use something reasonable.
this value will be then insert into a database.

If this is some code to assemble a SQL statement then this
is definitely not correct - you would need a textual repre-
sentation of 'value', not a copy of its binary value. To
get a textual representation of a value into a string use
sprintf().
On windows machine it works well, on Solaris not. The windows and
solaris path into c language is the same.

What does this second sentence mean? I never heard about a "path
into c language".
I'd like to say also that real value works correctly also if they are
used in the same manner:
memcpy(string, (real *) value, len)

Sorry, there's no 'real' type in C. Is this typedef-ed somewhere?
And if 'real' has a different size than a long int is this re-
flected in the value of 'len'?
Is there a particular manner to use long values on solaris?
Or to use memcpy with long types?

There's nothing special about using long int values on Solaris
(or any other system) if you use a reasonable (i.e. standard-
compliant) C compiler.
Thank you very much, I hope to be clear.

Sorry, it's rather unclear. Post at least some more context -
just a single line of code doesn't help, especially if you
don't tell what variables are that you use or what the
result of the memcpy() is going to be used for - the bit
about "insert into a database" doesn't mean a thing.

Regards, Jens
 
S

silvia.fama

Sorry, I tried to simplify but I was not clear!

I said real but it's a double type.
I need to put a long value type or a real value type into a string.
This value then will be inserted into an oracle database.

to put this value into a string I do:
memcpy(string, value, sizeof(long)); for long type
or
memcpy(string, value, sizeof(double)); for a double type

On windows these assignment works well and in Oracle database I see the
right values.
On Solaris only the value of double type works well, I mean that is
correctly updated into the database.
The value of long type is not correctly inserted into the database
cause it's inserted the zero value.

So I think that double and long types are managed in a different way by
solaris, and long is managed in a different way by windows and by
solaris. I also thought to "endian" but it should effect also double,
isn't it?


Thank you, I hope to have explained better!

Kind regards


Chris Dollin ha scritto:
Hi!
I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

This code is almost certainly wrong, but because you haven't
shown us any of the other declarations and uses it's hard
to say what, exactly, is wrong.

I say it's wrong because you have a cast `(long *) value`. Either
`value` is a pointer type (even though you imply that it's a long),
in which case you don't need the cast [1], or it isn't, in which
case you're handing a non-pointer to `memcpy`, BOOM.

I wonder if you meant `&value`? In which case, again, you don't
need the cast [1].

How many bytes are you copying? We don't know what `len` is.
One hopes that it's `sizeof(long)`. One also hopes that the
"string" location is long enough. One hopes that it has enough
space for the terminating 0. The code you show doesn't put the
terminating 0 in. Of course, maybe some unshown code does. Or
perhaps "string" isn't the right name for the variable.

How many bytes is the database expecting? What makes you think
that `len` is the right number, and what makes you think that a
`long` is exactly that wide? Because if a `long` is shorter
than that, you'll be copying rubbish; and if longer, you'll miss
out on some bytes, maybe the most relevant ones [2].
On windows machine it works well, on Solaris not.

What kind of ill working do you see?
The windows and solaris path into c language is the same.

"I don't know what that means" [3].

I suspect you're hitting an endianness / sizeof problem,
which because you didn't anticipate it may be a right
buxxer to fix.

[1] Assuming that you've remembered to #include <string.h>.

[2] EG if the `long` has the value `17`, the bytes holding the
`17` are the relevant ones.

[3] Bones.
 
S

silvia.fama

Sorry,
I add some information.

The value have to be copied into a string with memcpy cause the value
are binded into the sql queries and not explicitly defined (insert into
.... values:)value1, value2) is a sample query where value1 and value2
are bind variables). So I don't need the "character" value of the long
value but the "binary" value, so... memcpy!

And then, yes, the string size is correct!

Thanks!


(e-mail address removed) ha scritto:
Sorry, I tried to simplify but I was not clear!

I said real but it's a double type.
I need to put a long value type or a real value type into a string.
This value then will be inserted into an oracle database.

to put this value into a string I do:
memcpy(string, value, sizeof(long)); for long type
or
memcpy(string, value, sizeof(double)); for a double type

On windows these assignment works well and in Oracle database I see the
right values.
On Solaris only the value of double type works well, I mean that is
correctly updated into the database.
The value of long type is not correctly inserted into the database
cause it's inserted the zero value.

So I think that double and long types are managed in a different way by
solaris, and long is managed in a different way by windows and by
solaris. I also thought to "endian" but it should effect also double,
isn't it?


Thank you, I hope to have explained better!

Kind regards


Chris Dollin ha scritto:
Hi!
I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

This code is almost certainly wrong, but because you haven't
shown us any of the other declarations and uses it's hard
to say what, exactly, is wrong.

I say it's wrong because you have a cast `(long *) value`. Either
`value` is a pointer type (even though you imply that it's a long),
in which case you don't need the cast [1], or it isn't, in which
case you're handing a non-pointer to `memcpy`, BOOM.

I wonder if you meant `&value`? In which case, again, you don't
need the cast [1].

How many bytes are you copying? We don't know what `len` is.
One hopes that it's `sizeof(long)`. One also hopes that the
"string" location is long enough. One hopes that it has enough
space for the terminating 0. The code you show doesn't put the
terminating 0 in. Of course, maybe some unshown code does. Or
perhaps "string" isn't the right name for the variable.

How many bytes is the database expecting? What makes you think
that `len` is the right number, and what makes you think that a
`long` is exactly that wide? Because if a `long` is shorter
than that, you'll be copying rubbish; and if longer, you'll miss
out on some bytes, maybe the most relevant ones [2].
On windows machine it works well, on Solaris not.

What kind of ill working do you see?
The windows and solaris path into c language is the same.

"I don't know what that means" [3].

I suspect you're hitting an endianness / sizeof problem,
which because you didn't anticipate it may be a right
buxxer to fix.

[1] Assuming that you've remembered to #include <string.h>.

[2] EG if the `long` has the value `17`, the bytes holding the
`17` are the relevant ones.

[3] Bones.
 
C

Chris Dollin

(e-mail address removed) wrote:

(Please don't top-post. Your reply should follow, or be
interspersed with, the message you're replying to. Trim
away irrelevant material, of course.)
Sorry, I tried to simplify but I was not clear!

Hence "show exact code". If you don't know what's wrong,
you don't know what to simplify, and you don't know what
to leave out. Preferably you want a small example that
is complete ie can be compiled and run.
I said real but it's a double type.
I need to put a long value type or a real value type into a string.

That doesn't sound very safe. In fact it sounds completely
/un/safe. Depending on what you mean, exactly.
This value then will be inserted into an oracle database.

to put this value into a string I do:
memcpy(string, value, sizeof(long)); for long type
or
memcpy(string, value, sizeof(double)); for a double type

So all that stuff about (long *) was irrelevant?

It /looks/ like what you're doing is putting the bytes that
comprise the value into `string` and then, by implementation-
specific magic, sending them to the database. I hope that the
magic can cope with any character whatsoever in a string value.
I hope that you only ever do this on a single implementation,
because /different implementations use different representations
for the same C type/. Oops.
On windows these assignment works well and in Oracle database I see the
right values.

What are those "right values"?
On Solaris only the value of double type works well, I mean that is
correctly updated into the database.
The value of long type is not correctly inserted into the database
cause it's inserted the zero value.

I suspect that your Solaris long has sizeof > your Windows long.
So I think that double and long types are managed in a different way by
solaris, and long is managed in a different way by windows and by
solaris. I also thought to "endian" but it should effect also double,
isn't it?

That depends. (Probably yes.) But I think the sizeof is your
problem. As a wiser hedgehog than I said:

You have to decide exactly what you want to store for your
long (and double) values and what platforms you might want
to use. Myself I'd have written the usual decimal representaion
and told the database the values were integers and floats,
and let /it/ handle the conversion issues.
 
C

Chris Dollin

The value have to be copied into a string with memcpy cause the value
are binded into the sql queries and not explicitly defined (insert into
... values:)value1, value2) is a sample query where value1 and value2
are bind variables). So I don't need the "character" value of the long
value but the "binary" value, so... memcpy!

That makes no sense to me at all. Sorry.
And then, yes, the string size is correct!

Coincidences happen. Be afraid.
 
B

Ben Bacarisse

Sorry, I tried to simplify but I was not clear!

Please don't top post. Read this page:
http://www.netmeister.org/news/learn2quote2.html
Chris Dollin ha scritto:
I said real but it's a double type.
I need to put a long value type or a real value type into a string.
This value then will be inserted into an oracle database.

You have essentially just repeated your question. Chris Dollin's key
point was that no one can tell what is wrong with this code without
seeing more. *At the very least* you must post the types of the
variables used, the value in "len" and something that describes the
storage pointed to by "string".

But that is *at the very least*. Much better would be enough of the
code to see the operation though from getting the value to inserting
it. I stop just short of asking for a complete program, because you'd
have to take all the DB stuff out, but a full, working program that
exhibits the same problem would be the best thing to post.
to put this value into a string I do:
memcpy(string, value, sizeof(long)); for long type
or
memcpy(string, value, sizeof(double)); for a double type

You do something like that. The above lines would not compile, so you
probably typed it in rather cutting and pasting. Post the actual
code. And more of it![1]

[1] Two people overheard by Alan Bennett:
"The food here is awful." "Yes, and so little of it!"
 
J

jacob navia

(e-mail address removed) a écrit :
Hi!
I'm using c language.
I need to copy a long type value into a char string using a memcpy
function:
memcpy(string, (long *) value, len)
this value will be then insert into a database.

On windows machine it works well, on Solaris not. The windows and
solaris path into c language is the same.
I'd like to say also that real value works correctly also if they are
used in the same manner:
memcpy(string, (real *) value, len)

Is there a particular manner to use long values on solaris?
Or to use memcpy with long types?

Thank you very much, I hope to be clear.

Yes, this is an endianess problem.

Yesterday, I had the same problem in the power pc. I was copying
data using memcpy, and it worked in the windows version and it will
not work under the power pc, and I suppose that the SPARC is big
endian too. I was getting all zeroes.

I fixed it by making a pointer of the appropiate type. In
your case you would do:

long *pLong = (long *)string;
*pLong = (long)value;

That should work.
 
M

Martin Ambuhl

/* !"(e-mail address removed)" <silvia.fama @ googlemail.com>
* in a message with subject "long type in solaris"
* <1169041039.675744 .40760 @ m58g2000cwm.googlegroups.com > asks:

* "I need to copy a long type value into a char string using a memcpy
* function: memcpy(string, (long *) value, len) this value will be then
* insert into a database.

* On windows machine it works well, on Solaris not. The windows and
* solaris path into c language is the same. I'd like to say also that
* real value works correctly also if they are used in the same manner:
* memcpy(string, (real *) value, len)

* Is there a particular manner to use long values on solaris? Or to
* use memcpy with long types?"

This question looks like you are very confused. Those casts are silly
and wrong: memcpy () takes a void * as its second argument. Are you
_sure_ you want to copy the internal representation of the value (what
memcpy does) rather than a specific external representation (what
something in the *printf does)?

There is nothing special about whether that second argument points to a
long or to some real type('real *' means nothing in C). Please examine
the following, noting the parallelism: */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
size_t howmuch;
char *target;
long int long_source = 3700, *long_source_ptr = &long_source;
double double_source = 37.37, *double_source_ptr = &double_source;

/* allocating the char array */
howmuch = sizeof(long) >= sizeof(double) ? sizeof(long) :
sizeof(double);
if (!(target = malloc(howmuch))) {
fprintf(stderr, "%s\n", "malloc failed, bailing ...\n");
exit(EXIT_FAILURE);
}

/* storing a long into the char array & checking. */
memcpy(target, &long_source, sizeof long_source);
printf("Copied %ld from long_source, target now has %ld\n\n",
long_source, *(long *) target);
long_source++;
printf("long_source has been incremented.\n");
memcpy(target, long_source_ptr, sizeof *long_source_ptr);
printf("Copied %ld through long_source_ptr, target now has %ld\n\n",
*long_source_ptr, *(long *) target);


/* storing a double into the char array & checking. */
memcpy(target, &double_source, sizeof double_source);
printf("Copied %g from double_source, target now has %g\n\n",
double_source, *(double *) target);
double_source++;
printf("double_source has been incremented.\n");
memcpy(target, double_source_ptr, sizeof *double_source_ptr);
printf("Copied %g through double_source_ptr, target now has %g\n\n",
*double_source_ptr, *(double *) target);

return 0;
}

[output]

Copied 3700 from long_source, target now has 3700

long_source has been incremented.
Copied 3701 through long_source_ptr, target now has 3701

Copied 37.37 from double_source, target now has 37.37

double_source has been incremented.
Copied 38.37 through double_source_ptr, target now has 38.37
 
M

matevzb

Yes, this is an endianess problem.

Yesterday, I had the same problem in the power pc. I was copying
data using memcpy, and it worked in the windows version and it will
not work under the power pc, and I suppose that the SPARC is big
endian too. I was getting all zeroes.
The whole char array was zeroes? What was the size of the array and
sizeof(long) in your case? I find it hard to believe that memcpy()-ing
a long (with value !=0) to a char array would yield zeroes, and even
harder that this is an endianness problem. Perhaps you were
memcpy()-ing 4 bytes of a 64-bit long?
I fixed it by making a pointer of the appropiate type. In
your case you would do:

long *pLong = (long *)string;
*pLong = (long)value;

That should work.
But only if string is properly aligned, otherwise it will dump core
(bus error probably).
 
K

Keith Thompson

Sorry, I tried to simplify but I was not clear!

I said real but it's a double type.
I need to put a long value type or a real value type into a string.
This value then will be inserted into an oracle database.

to put this value into a string I do:
memcpy(string, value, sizeof(long)); for long type
or
memcpy(string, value, sizeof(double)); for a double type

You're passing "value" to memcpy()?

Either:

(a) value is of some pointer type (in which case "value" is probably a
poor name), or
(b) you're ignoring an error message, or
(c) you're missing the required "#include <string.h>", so the compiler
doesn't know what argument types memcpy() expects, or
(d) the code you've shown us isn't your actual code.
 
K

Keith Thompson

jacob navia said:
Yes, this is an endianess problem.

Quite possibly, but I don't think the OP has yet given us enough
information to be sure of that.
Yesterday, I had the same problem in the power pc. I was copying
data using memcpy, and it worked in the windows version and it will
not work under the power pc, and I suppose that the SPARC is big
endian too. I was getting all zeroes.

jacob, can you show us the actual code that had this problem? I don't
see how an endianness problem would give you all zeroes unless, as
matevzb mentioned.
I fixed it by making a pointer of the appropiate type. In
your case you would do:

long *pLong = (long *)string;
*pLong = (long)value;

That should work.

Only if "string" (assuming that's a pointer or array) is properly
aligned, as matevzb pointed out. I think x86 and PowerPC quietly
handle misaligned accesses; other systems may not. If your own code
is intended to work only on those systems, that's fine, but the OP is
apparently trying to get his code to work on multiple systems, *maybe*
including SPARC with its strict alignment requirements.

Yes, SPARC is big-endian -- but the OP didn't mention SPARC, just
Solaris, which also runs on x86 systems.

The cast in your second line is unnecessary. For that matter, so is
the temporary pointer variable. *If* you could assume proper
alignment, the following should work:

*(long*)string = value;

(assuming, of course, that value is of type long; the OP hasn't made
that clear either).

But the only safe way to copy arbitrary data into a character array is
to use memcpy(). Well, you could copy the bytes one at a time, but
this is just what memcpy() is for.
 
J

jacob navia

The code I have is this

static void AddToDataSegment(long long value,int siz)
{
short *pShort;
int *pInt;
long long *pLongLong;
switch (siz) {
case 1:
DataSegment[DataSegmentIndex] = (char)(value&0xff);
break;
case 2:
pShort = (short *)(&DataSegment[DataSegmentIndex]);
*pShort = (short)(value&0xffff);
break;
case 4:
pInt = (int *)(&DataSegment[DataSegmentIndex]);
*pInt = (int)(value&0xffffffff);
break;
case 8:
pLongLong = (long long *)(&DataSegment[DataSegmentIndex]);
*pLongLong = value;
break;
default:
assert(0);
}

}

before I had

memcpy(&DataSegment[DataSegmentIndex],&value,siz);

This copied the data into the wrong side of the destination,
so that when I read it I had zero in the lsb and the data
in the msb.

Under windows this works.
 
J

jacob navia

Sh...!!!
I forgot:

DataSegment is a char *, and DataSegmentIndex an int. (globals)

Besides, I align the index before making the copy.
 
K

Keith Thompson

jacob navia said:
The code I have is this

static void AddToDataSegment(long long value,int siz)
{
short *pShort;
int *pInt;
long long *pLongLong;
switch (siz) {
case 1:
DataSegment[DataSegmentIndex] = (char)(value&0xff);
break;
case 2:
pShort = (short *)(&DataSegment[DataSegmentIndex]);
*pShort = (short)(value&0xffff);
break;
case 4:
pInt = (int *)(&DataSegment[DataSegmentIndex]);
*pInt = (int)(value&0xffffffff);
break;
case 8:
pLongLong = (long long *)(&DataSegment[DataSegmentIndex]);
*pLongLong = value;
break;
default:
assert(0);
}

}

before I had

memcpy(&DataSegment[DataSegmentIndex],&value,siz);

This copied the data into the wrong side of the destination,
so that when I read it I had zero in the lsb and the data
in the msb.

And as you wrote in a followup:
| DataSegment is a char *, and DataSegmentIndex an int. (globals)
|
| Besides, I align the index before making the copy.

Every cast in that code is unnecessary and, in my opinion, merely
serves to obfuscates the code. The temporaries pShort et al are not
strictly necessary, but I can see that they simlify the code slightly
(I'm not sure whether I would have used them myself).

Aligning the index is fine, as long as DataSegment itself is properly
aligned. The only portable way to do that would be for DataSegment to
be a pointer returned by malloc() (or calloc() or realloc()), but
perhaps you do it in some non-portable way.
Under windows this works.

As far as I can see, it should work as long as the types short, int,
and long long have the sizes you assume, CHAR_BIT==8, and both
DataSegment and DataSegmentIndex are (somehow) properly aligned. But
I think it would be clearer and more robust if you used unsigned types
throughout.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,068
Latest member
MakersCBDIngredients

Latest Threads

Top