473,732 Members | 2,219 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 2535
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**********@g emini.csx.cam.a c.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\00 0\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.n et> writes:
In article <cs**********@g emini.csx.cam.a c.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_Keit h) 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
2968
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) struct, I am storing an array of 27 pointers and a void pointer that can point to anything. typedef struct trieNode { struct trieNode *children; // The children nodes void *obj; // The object stored } TrieNode;
204
13046
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 = {0,1,2,4,9};
5
3522
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 accepts a void* key argument, and uses the functions above to store this argument. It returns something (linked to the key) that the caller can store a value in. The actual key argument is always of the same pointer type (as seen in the caller,...
5
1770
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 = 0 To 2 For j = 0 To 2 a(i, j) = 2 * a(i, j) Underlined as latebinding error Next Next
15
3838
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> typedef struct _tnode_t { void *content; struct _tnode_t *kids;
7
2194
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 the differences between: (1)ElemType array (2)array=(ElemType*)malloc(N*size of(ElemType)) or array=(ElemType*)calloc(N,size of(ElemType))
9
1812
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 lines.
9
2448
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
1768
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
8946
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9447
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9181
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8186
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6735
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4550
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3261
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 we have to send another system
2
2721
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2180
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.