473,498 Members | 1,833 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Array assignment via cast

Hi,

I frequently do non-initialisation type structure assignment via casting:

e.g.

struct s{int i,j,k;} mys;
....
mys=(struct s){3,4,5};

is this possible with an array?
eg char test[10];

.... is it possible to assign to test via a cast? is it legal?

Thanks
Nov 14 '05 #1
7 2513
James Mcguire <no@one.com> wrote:
I frequently do non-initialisation type structure assignment via casting: mys=(struct s){3,4,5};

is this possible with an array?


No. An array is not a modifiable lvalue, and therefore cannot be
assigned to. It _can_ be initialised, but that's another part of the
syntax (using identically-spelled tokens, but that makes no difference).

Richard
Nov 14 '05 #2
On Tue, 18 Jan 2005 13:21:46 +0000, James Mcguire wrote:
Hi,

I frequently do non-initialisation type structure assignment via casting:

e.g.

struct s{int i,j,k;} mys;
...
mys=(struct s){3,4,5};
This is not a cast, it is called a compound literal and is a "new" feature
introduced in C99. If you aren't targetting C99 compilers specifically you
probably shouldn't use it.
is this possible with an array?
eg char test[10];


Arrays are not modifiable lvalues and cannot be assigned to. Probably the
nearest you can get is something like

static const char initdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
memcpy(test, initdata, sizeof test);

Lawrence

Nov 14 '05 #3
In article <cs**********@gemini.csx.cam.ac.uk>
James Mcguire <no@one.com> wrote:
I frequently do non-initialisation type structure assignment via casting:

e.g.

struct s{int i,j,k;} mys;
...
mys=(struct s){3,4,5};
This is not actually a cast. It is instead a C99-standard form
called a "compound literal". The syntax for a compound literal
is:

( type-name ) { list-of-values }

and of course the (, type-name, ) sequence looks exactly like a
cast. (So why not call it one? Well, because the C99 standard
calls it something else -- so if you want to communicate with
C programmers who have read the C99 standard, or a good book
about C99, presumably you would want to use the same words. Also,
because you can include the "const" qualifier to good effect.)
is this possible with an array?
eg char test[10];
No. You can construct a compound-literal with array type:

(const char [10]){'a', 'b', 'c'}

has a pretty similar meaning to:

"abc\000\000\000\000\000\000"

Both of these produce an anonymous array object containing 10
"char"s (note that the string literal has 9 characters in it, a +
b + c + six copies of \000 + the terminating '\0' that is always
included for string literals = 10 chars). Both are allowed to
place the array in read-only storage. The biggest difference
between the two is that, in a quirk having to do with history, the
string literal produces the type "array 10 of char" while the
compound literal has type "array 10 of const char".

(String-literal-produced arrays really should have "const char",
but ancient C had no "const" type, and this would have invalidated
huge quantities of existing code, had the 1989 C standard made
them "const".)

The problem is, even having produced an array object, you cannot
assign it to another array:

struct s s1, s2;
...
s1 = s2; /* is OK */

but:

char a1[10], a2[20];
...
a1 = a2; /* not OK, requires a diagnostic */
... is it possible to assign to test via a cast? is it legal?


Again, it is not a cast, it is a "compound literal"; and no, ordinary
assignment will not work, just as it does not work with actual
array objects: the left hand side, a1 in the example above, is not
a "modifiable lvalue", and the right hand side expression undergoes
the transform prescribed by The Rule, becoming a pointer value.

Hence, just as you must memcpy() or strcpy() arrays or strings
into their target buffers, you must also memcpy() the compound
literal:

assert(sizeof a1 <= sizeof a2); /* assumed in memcpy call */
memcpy(a1, a2, sizeof a1); /* copy the parts of a2 that fit */
...
memcpy(a1, (const char [sizeof a1]){'a', 'b', 'c'}, sizeof a1);

Note that if you leave out the "const" in a compound literal, the
compiler is obligated to create a fresh copy whenever the enclosing
block is entered, in case you take a pointer to the literal and
then modify it:

% cat t.c
#include <stdio.h>

int main(void) {
for (int i = 0; i < 3; i++) {
char *p = (char []) { 'h', 'e', 'l', 'l', 'o', '\0' };
if (i == 1)
p[0] = 'j';
puts(p);
}
return 0;
}
% cc -std=c99 -O -o t t.c -W -Wall
% ./t
hello
jello
hello
%

This means that the non-"const" version generally invokes an internal
memcpy() from a "clean" copy each time the block is entered. Using
the "const" can avoid paying for these copies. (A smart compiler
will attempt to figure out whether the copy is required, but using
"const" can save programmer effort too, as the programmer no longer
has to wonder whether the compound literal ever gets modified.)

(GCC seems to make a copy every time, even when the compound literal
uses "const". This probably has to do with "gcc -std=c99" not
actually implementing C99, but rather something somewhere between
GNUC and C99. I suspect the GNUC language did not have this special
"one static copy is OK" property for const-qualified compound
literals.)
--
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.
Nov 14 '05 #4
rss
Thank you for your incredibly detailed and concise answer.

I have a off-topic question; it's becoming apparent that in order to become
a more effective C programmer I need to learn more about the standard.
What is the best way of perusing this? I took a look at the FAQ and have
access to a copy of the C99 standard, but it seems incredibly dense reading
that doesn't seem to make much sense to a person mof my experience. Are
there any alternative sources of information that would help?

Thanks
Nov 14 '05 #5
Chris Torek <no****@torek.net> writes:
In article <cs**********@gemini.csx.cam.ac.uk>
James Mcguire <no@one.com> wrote:
I frequently do non-initialisation type structure assignment via casting:

e.g.

struct s{int i,j,k;} mys;
...
mys=(struct s){3,4,5};


This is not actually a cast. It is instead a C99-standard form
called a "compound literal". The syntax for a compound literal
is:

( type-name ) { list-of-values }

and of course the (, type-name, ) sequence looks exactly like a
cast. (So why not call it one? Well, because the C99 standard
calls it something else -- so if you want to communicate with
C programmers who have read the C99 standard, or a good book
about C99, presumably you would want to use the same words. Also,
because you can include the "const" qualifier to good effect.)

[...]

Another good reason not to call it a cast is that it isn't one.

A cast-expression looks like:

( type-name ) expression

(that's a bit of an over-simplification for reasons that aren't
relevant to this discussion). The operand has to be an expression,
which is converted to the named type.

In a compound literal, the

{ list-of-values }

is not an expression, and no conversion takes place; instead, the
type-name tells the compiler what the type of the expression is. The
only thing it has in common with a cast is that it includes a type
name in parentheses.

--
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.
Nov 14 '05 #6
rss wrote:
Thank you for your incredibly detailed and concise answer.

I have a off-topic question; it's becoming apparent that in order to become
a more effective C programmer I need to learn more about the standard.
What is the best way of perusing this? I took a look at the FAQ and have
access to a copy of the C99 standard, but it seems incredibly dense reading
that doesn't seem to make much sense to a person mof my experience. Are
there any alternative sources of information that would help?

Thanks


This place itself is a definitive resource. Keep reading. ;)

Regards,
Jonathan.

--
C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
C Library: http://www.dinkumware.com/refxc.html
C99 Standard Draft: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/

"I'm learning to program because then I can write
programs to do my homework faster." - Andy Anfilofieff
Nov 14 '05 #7
rss wrote:
Thank you for your incredibly detailed and concise answer.

I have a off-topic question; it's becoming apparent that in order to become
a more effective C programmer I need to learn more about the standard.
What is the best way of perusing this? I took a look at the FAQ and have
access to a copy of the C99 standard, but it seems incredibly dense reading
that doesn't seem to make much sense to a person mof my experience. Are
there any alternative sources of information that would help?


I would suggest getting a copy of The C Programming Language, Second
Edition, by Kernighan & Ritchie. It is the main reference that I use.
The only system specific stuff is one chapter called The UNIX System
Interface which is fairly obvious, the rest is all portable.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
2900
by: fix | last post by:
Hi all, I feel unclear about what my code is doing, although it works but I am not sure if there is any possible bug, please help me to verify it. This is a trie node (just similar to tree nodes)...
204
12883
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
5
3496
by: Stijn van Dongen | last post by:
A question about void*. I have a hash library where the hash create function accepts functions unsigned (*hash)(const void *a) int (*cmp) (const void *a, const void *b) The insert function...
5
1759
by: mark | last post by:
I know I am being incredibly dunderheaded about this consider the following: STRICT ON Dim a(,) As Double = {{1, 2}, {3, 4}, {5, 6}} Private Sub T1(ByVal a As Array) Dim i, j As Integer For i =...
15
3812
by: Paminu | last post by:
Still having a few problems with malloc and pointers. I have made a struct. Now I would like to make a pointer an array with 4 pointers to this struct. #include <stdlib.h> #include <stdio.h>...
7
2175
by: Yuri_Юрий | last post by:
I'm confused about the VARIABLE LENGTH ARRAYS. {scanf("%d",&n);float a;} In which compiler can I use it? I tried VC++6.0 SP6,but it's reported error:CONSTANT EXPRESSION! Another question, What...
9
1800
by: removeps-generic | last post by:
I have struct X { double array; }; I want to form a pointer to the 5th element of X::array. The type of the pointer should be "double X::*" or "double* X::*" or something along those...
9
2434
by: Leon_Amirreza | last post by:
How Can I cast a uint type to a byte? Does the following code do this? uint a = 5; byte b = new byte; b = (byte)a;
14
1746
by: KK | last post by:
Dear All I have a small problem with using as operator on value type array. Here is an example what I am trying to do. using System; using System.Collections.Generic; using System.Text;
0
7167
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6890
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7379
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4915
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4593
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3095
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3085
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1423
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
657
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.