By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,973 Members | 1,854 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,973 IT Pros & Developers. It's quick & easy.

long type in solaris

P: n/a
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.

Jan 17 '07 #1
Share this Question
Share on Google+
28 Replies


P: n/a
si*********@googlemail.com wrote:
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.

--
Clark S. Cox III
cl*******@gmail.com
Jan 17 '07 #2

P: n/a
si*********@googlemail.com wrote:
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)

Jan 17 '07 #3

P: n/a
si*********@googlemail.com wrote:
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.

--
Chris "electric hedgehog" Dollin
"People are part of the design. It's dangerous to forget that." /Star Cops/

Jan 17 '07 #4

P: n/a
"si*********@googlemail.com" <si*********@googlemail.comwrote:
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
Jan 17 '07 #5

P: n/a
si*********@googlemail.com wrote:
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.
>
Thank you very much, I hope to be clear.
Jan 17 '07 #6

P: n/a
si*********@googlemail.com <si*********@googlemail.comwrote:
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
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
Jan 17 '07 #7

P: n/a
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:
si*********@googlemail.com wrote:
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.

--
Chris "electric hedgehog" Dollin
"People are part of the design. It's dangerous to forget that." /Star Cops/
Jan 17 '07 #8

P: n/a
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!
si*********@googlemail.com 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:
si*********@googlemail.com wrote:
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.

--
Chris "electric hedgehog" Dollin
"People are part of the design. It's dangerous to forget that." /Star Cops/
Jan 17 '07 #9

P: n/a
si*********@googlemail.com 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:
>I suspect you're hitting an endianness / sizeof problem,
which because you didn't anticipate it may be a right
buxxer to fix.
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.

--
Chris "electric hedgehog" Dollin
The shortcuts are all full of people using them.

Jan 17 '07 #10

P: n/a
si*********@googlemail.com wrote:
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.

--
Chris "scary hedgehog" Dollin
The "good old days" used to be much better.

Jan 17 '07 #11

P: n/a
"si*********@googlemail.com" <si*********@googlemail.comwrites:
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:
>si*********@googlemail.com wrote:
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.
<helpful guesses snipped>
>
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!"

--
Ben.
Jan 17 '07 #12

P: n/a
si*********@googlemail.com 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.
Jan 17 '07 #13

P: n/a

/* !"si*********@googlemail.com" <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
Jan 17 '07 #14

P: n/a
On Jan 17, 4:17 pm, jacob navia <j...@jacob.remcomp.frwrote:
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).
--
WYCIWYG - what you C is what you get

Jan 17 '07 #15

P: n/a
"si*********@googlemail.com" <si*********@googlemail.comwrites:
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 17 '07 #16

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 17 '07 #17

P: n/a
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.
Jan 17 '07 #18

P: n/a
Sh...!!!
I forgot:

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

Besides, I align the index before making the copy.
Jan 17 '07 #19

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 17 '07 #20

P: n/a
si*********@googlemail.com wrote:
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?
Could I suggest that you find someone who knows C and is patient, show
them the code, explain what you want to achieve and get their advice?

What you have been posting here makes me very, very afraid what will
happen to your database.

Jan 18 '07 #21

P: n/a
In article <45***********************@news.orange.fr>
jacob navia <ja***@jacob.remcomp.frwrote:
>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);
}

}
I would attempt to avoid the above entirely in the first place,
but give the above interface, I would probably write this as:

/*
* Writes a value (supplied here as a long long) to
* DataSegment[DataSegmentIndex .. DataSegmentIndex + siz - 1]
* using the host machine's byte order, whatever that is.
* Makes the nonportable assumption that sizeof(short)==2,
* sizeof(int)==4, and sizeof(long long)==8, when int16_t,
* int32_t, and int64_t are not available.
*
* Note that the supplied value is assumed to fit in the
* target type, in all cases. For instance, supplying siz==1
* means that value should be between CHAR_MIN and CHAR_MAX
* inclusive (typically -128 to 127, or 0 to 255). If the
* value is out of range the effect is undefined.
*/
static void AddToDataSegment(long long value, int siz) {
char *p = &DataSegment[DataSegmentIndex];
#ifdef INT16_MAX
int16_t sval;
#else
short sval;
#endif
#ifdef INT32_MAX
int32_t ival;
#else
int ival;
#endif
#ifdef INT64_MAX
int64_t llval;
#else
long long llval;
#endif
switch (siz) {
case 1:
*p = value;
break;
case 2:
sval = value;
memcpy(p, &sval, siz);
break;
case 4:
ival = value;
memcpy(p, &ival, siz);
break;
case 8:
llval = value;
memcpy(p, &llval, siz);
break;
default:
panic("AddToDataSegment");
/* NOTREACHED */
}
}

This avoids any alignment constraints. The code is designed to
offer a smart compiler easy opportunities for optimization, too:
little-endian machines could turn this into:

[when siz==2, 4, or 8]

copy "value" from argument register(s) to llval-in-memory

push (value of p)
push (address of llval)
push (siz)
call memcpy

where big-endian machines could get:

copy "value" from argument register(s) to llval-in-memory

push (value of p)
push (address of llval + 8 - siz)
push (siz)
call memcpy

and then perhaps expand memcpy in-line if appropriate.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jan 18 '07 #22

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
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);
}

}
[...]

I had another couple of thoughts about this code.

If the siz argument happens to be constant for each call, you could
break this up into 4 separate functions, each of which just uses the
appropriate type. You have to know the siz argument when writing a
call; having to know which function to call is no more difficult. If
the siz argument isn't always constant, you can't do this.

Also, why "siz" rather than "size"?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '07 #23

P: n/a
Chris Torek a écrit :
In article <45***********************@news.orange.fr>
jacob navia <ja***@jacob.remcomp.frwrote:
>>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);
}

}


I would attempt to avoid the above entirely in the first place,
but give the above interface, I would probably write this as:

/*
* Writes a value (supplied here as a long long) to
* DataSegment[DataSegmentIndex .. DataSegmentIndex + siz - 1]
* using the host machine's byte order, whatever that is.
* Makes the nonportable assumption that sizeof(short)==2,
* sizeof(int)==4, and sizeof(long long)==8, when int16_t,
* int32_t, and int64_t are not available.
*
* Note that the supplied value is assumed to fit in the
* target type, in all cases. For instance, supplying siz==1
* means that value should be between CHAR_MIN and CHAR_MAX
* inclusive (typically -128 to 127, or 0 to 255). If the
* value is out of range the effect is undefined.
*/
static void AddToDataSegment(long long value, int siz) {
char *p = &DataSegment[DataSegmentIndex];
#ifdef INT16_MAX
int16_t sval;
#else
short sval;
#endif
#ifdef INT32_MAX
int32_t ival;
#else
int ival;
#endif
#ifdef INT64_MAX
int64_t llval;
#else
long long llval;
#endif
switch (siz) {
case 1:
*p = value;
break;
case 2:
sval = value;
memcpy(p, &sval, siz);
break;
case 4:
ival = value;
memcpy(p, &ival, siz);
break;
case 8:
llval = value;
memcpy(p, &llval, siz);
break;
default:
panic("AddToDataSegment");
/* NOTREACHED */
}
}

This avoids any alignment constraints. The code is designed to
offer a smart compiler easy opportunities for optimization, too:
little-endian machines could turn this into:

[when siz==2, 4, or 8]

copy "value" from argument register(s) to llval-in-memory

push (value of p)
push (address of llval)
push (siz)
call memcpy

where big-endian machines could get:

copy "value" from argument register(s) to llval-in-memory

push (value of p)
push (address of llval + 8 - siz)
push (siz)
call memcpy

and then perhaps expand memcpy in-line if appropriate.
Thanks for the suggestions. I am writing this assembler in a hurry,
and you are right, I should have used C99 types, since IBM has a C99
compliant setup. I use IBM compiler to bootstrap mine, so the code has
to compile in both.
Jan 18 '07 #24

P: n/a
Keith Thompson a écrit :
jacob navia <ja***@jacob.remcomp.frwrites:
>>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);
}

}

[...]

I had another couple of thoughts about this code.

If the siz argument happens to be constant for each call, you could
break this up into 4 separate functions, each of which just uses the
appropriate type. You have to know the siz argument when writing a
call; having to know which function to call is no more difficult. If
the siz argument isn't always constant, you can't do this.
It can be ONLY 1, 2 4 or 8. I am sorry about the code but I am
writing it in a hurry. It is the first assembler I wrote since
two years or so, and I am a bit rusty. Anyway, I have planned
a cleanup phase later on, so I will come back to this and see
if I can change that to a function call. But switch is more readable
too...
Also, why "siz" rather than "size"?
I don't really know. It is an identifier that I use since years and
years and all sizes are siz. Why did I start doing this? I do not
remember, just an habit.

jacob
Jan 18 '07 #25

P: n/a
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
Thanks for the suggestions. I am writing this assembler in a hurry,
and you are right, I should have used C99 types, since IBM has a C99
compliant setup. I use IBM compiler to bootstrap mine, so the code has
to compile in both.
IBM has a C99 compliant compiler? Do you mean that it's fully
conforming, or just close enough for your purposes? Which compiler is
it?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 18 '07 #26

P: n/a
Keith Thompson a écrit :
jacob navia <ja***@jacob.remcomp.frwrites:
[...]
>>Thanks for the suggestions. I am writing this assembler in a hurry,
and you are right, I should have used C99 types, since IBM has a C99
compliant setup. I use IBM compiler to bootstrap mine, so the code has
to compile in both.


IBM has a C99 compliant compiler? Do you mean that it's fully
conforming, or just close enough for your purposes? Which compiler is
it?
According to the documentation:
-qlanglvl=<suboptions_list>
Selects the language level and language options for
the compilation. <suboptions_listis a colon-
separated list of suboptions. The suboptions are:

[snip long list of C89 and other standards supported]

stdc99
Compilation conforms to the ISO C99 standard.
extc89
Compilation conforms to the ANSI C89 standard,
and accepts implementation-specific language
extensions.
extc99
Compilation conforms to the ISO C99 standard,
and accepts implementation-specific language
extensions.

There are no other restrictions in the documentation. It is a very
flexible compiler, can compile 32/64 bits, with vectorization options
and optimizations options, very sophisticated.

[jacob@ppcibm lccppc]$ cc -qversion
IBM XL C/C++ Enterprise Edition V8.0 for AIX
Version: 08.00.0000.0000
[jacob@ppcibm lccppc]$
Jan 18 '07 #27

P: n/a
On Jan 18, 11:50 pm, jacob navia <j...@jacob.remcomp.frwrote:
Keith Thompson a écrit :
jacob navia <j...@jacob.remcomp.frwrites:
[...]
>Thanks for the suggestions. I am writing this assembler in a hurry,
and you are right, I should have used C99 types, since IBM has a C99
compliant setup. I use IBM compiler to bootstrap mine, so the code has
to compile in both.
IBM has a C99 compliant compiler? Do you mean that it's fully
conforming, or just close enough for your purposes? Which compiler is
it?According to the documentation:
-qlanglvl=<suboptions_list>
Selects the language level and language options for
the compilation. <suboptions_listis a colon-
separated list of suboptions. The suboptions are:

[snip long list of C89 and other standards supported]

stdc99
Compilation conforms to the ISO C99 standard.
extc89
Compilation conforms to the ANSI C89 standard,
and accepts implementation-specific language
extensions.
extc99
Compilation conforms to the ISO C99 standard,
and accepts implementation-specific language
extensions.

There are no other restrictions in the documentation. It is a very
flexible compiler, can compile 32/64 bits, with vectorization options
and optimizations options, very sophisticated.
According to the Compiler Reference (found at
http://www-1.ibm.com/support/docview...utf-8&lang=en),
the compiler itself is conforming, but the headers/libraries may not
be:
"-qlanglvl <suboptions>
suboption: stdc99
Compilation conforms to the ISO C99 standard. Note: Not all
operating system releases support the header files and runtime library
required by C99."
--
WYCIWYG - what you C is what you get

Jan 19 '07 #28

P: n/a
matevzb a écrit :
"-qlanglvl <suboptions>
suboption: stdc99
Compilation conforms to the ISO C99 standard. Note: Not all
operating system releases support the header files and runtime library
required by C99."
Old releases of the OS probably are buggy. That covers those old
software. I haven't seen anything suspicious.
Jan 19 '07 #29

This discussion thread is closed

Replies have been disabled for this discussion.