Can't access an array-type member of a structure?

The Logic Designers must be crazy to have created such kind of mind troubling flow diagram to explain the working principle of the MCU instruction!

WRT to the original question:

Why can't I do: char s[10]; s = "012345678";

This is essentially because C/C++ does not have a "string" basic variable type.

s is an array of characters, and "012345678" is defined to be a pointer to an constant array of characters. The types don't match.

The fact that "xyz" is defined to be a pointer to an array of characters is sort of a hack. There aren't aren't reall any other "constants" that don't resolve to a basic type (ie NOT a pointer.)

The fact that char s[10] = "xyz"; works is a much bigger hack. It's pretty much syntactically inconsistent with the rest of C - there's no equivalent shortcut syntax for initializing any other type of array. I mean, I'm glad it's there, because having to say "char s[10] = {'x', 'y', 'z'}; would suck. But it's not ... elegant, language-wise.

Note that you can't actually assign ANYTHING to an array in C. The following will also produce an error (the same error, in fact.)

(long ramblings about the nature of variables might be forthcoming. But not particularly relevant to the original question.)

Enjoyable non-bureacratic popular write-up for beginners indeed!

Then can we write the following (though the value 012345678 is not entering into the space pointed by s)? *s = "012345678";

No. *s is not a "pointer to s", it is a de-reference of a pointer s (the value is "what s points to." In the case above, *s would be the char '0', and you still couldn't assign a "pointer to chars" to a "char."

You COULD have:

But you would "lose" "abcd" (it would be allocated in memory somewhere, but you would no longer know where.)

Questions are coming from my ignorance; the reponses are helping me to be educated.

This is the first time, I have heard that the following codes work because of "hack" (gain unauthorized access to data in a system or computer).

I had the understanding that the ASCII codes of the characters (012345678) are copied one-by-one (immediate addressing mode) into the respective memory locations allocated for the array named s[].

Now when you say "012345678" is a pointer (is defined to be a pointer), then I would like to revise my above understanding as follows:

While initializing s[] with "012345678", the characters are stored in an array space. The pointer (the base address) of the array space is used to read the charaters one-by-one, which are written into the destination space whose base address (the pointer) is in s. The following codes are supposed to be executed (in the backgorund) to implement "char s[10] = "012345678"; instruction in order to initialize s[].

“Hack” was probably a poor choice of words, especially when communicating with a relatively young person who doesn’t have English as their first language. Sorry. I meant definitions1-3 from The Original Hacker's Dictionary Maybe “kludge” - clever and useful, but not “pure and correct “

As a non-American speaker, "kludge" always seems to me to be etymologically too close to "klutz", and (to me) smacks of a clumsy, ugly or inappropriate fix, with no connotations of cleverness.

I'm happy with "hack".

Please don't use C-style casts, especially not on pointers or to cast away const .

Instead, preserve the const :

That's not correct. The type of a string literal is array of const char. As with all arrays, it might decay to a pointer when used in an expression, but the string literal itself is an array, not a pointer.

[lex.string] An ordinary string literal has type “array of n const char ” where n is the size of the string as defined below, has static storage duration (6.7.5), and is initialized with the given characters.

Or you can easily test this yourself:

Then the following codes (part of Post-67) are also "incorrect"?

The comment is incorrect, it's an array by definition. And it should be const char *ptrS . Casting a pointer to uint16_t is not portable either, as discussed earlier.

[conv.array] An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T” . [...] The result is a pointer to the first element of the array.

"123" is an array. It has an storage area in RAM space whose base address is termed as pointer . For an array, the name itself carries the base address (the pointer). What does it mean -- "decays to pointer"?

No. That's simply incorrect. It is an array, not a pointer. Please see my previous posts, read the standard quotes, and the demonstration: If you ask the compiler “what's the type of "123" ?” , it will tell you that it is an array of 4 constant characters . It is not a pointer to const char .

Just Google it: https://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay

I would like to revise my above understanding as follows: While initializing s with "012345678", the characters are stored in an array space. The pointer (the base address) of the array space is used to read the charaters one-by-one, which are written into the destination space whose base address (the pointer) is in s. The following codes are supposed to be executed (in the backgorund) to implement "char s[10] = "012345678"; instruction in order to initialize s. char s[10]; char *ptrS; ptrS = "012345678"; //"012345678" is pointer by definition Serial.println((uint16_t)ptrS, HEX); //shows: 112 char *ptrD; //pointer variable to point the destination space (the s[]) ptrD = s; for(int i=0; i<sizeof(s); i++) { char ch = *ptrS; *ptrD = ch; ++ptrS; ++ptrD; } Serial.println(s); //shows: 012345678

That's closer, but not right yet. No copying is involved. Well, there is a copy on AVR that copies all of the ".data" space into RAM, but that's just because of the flash not being directly addressable.

By the time to main(), some section of RAM has a copy of all of your initialized variables, including bytes 01234... beginning at some address xxxx. The compiler knew what address that would be, so s is just xxxx (an address, or 'pointer') When you call Serial.print(), xxxx (the address of the first byte of the string in RAM is passed as the argument - no additional copy occurs at runtime.

That makes the original problem even simpler to define. C does not support the assignment of a whole array to another. That's even exactly what the error message said, right? error: invalid array assignment

I call it a hack/kludge/whatever because C has no other mechanism for specifying a constant array (or other complex structure.) I don't think C++ does, either (though invoking a constructor to create an object is pretty close?) You can't say birthday.name = {'R', 'a', 'k', 'i', 'b', 0}; either, for example, because the {val, val, val} format is only for initializers; it doesn't "create" a constant.

Yeah, yeah. I was hoping to avoid dealing with "const" in this discussion, but I didn't want the code I posted to generate warnings, either. I'm vaguely annoyed that the type of string literals changed somewhere along the lines. Academically, anyway. I concede that it's almost always the right thing to do, but:

not behaving the same (s1 initialization gives a warning) is ... uncomfortable.

Does this mean they have a half-life? Decay products?

For struct types, it's fine, you can “create a constant”, just not for C-style arrays:

You can do this with structs and C++ arrays without issues, but not with C-style arrays:

When did it change?

AFAIK, string literals have always been read-only, even in C. But in C, the type is (confusingly) char[n] , not const char[n] , even though trying to write to it is a bug. Possibly because string literals predate the const keyword?

In C++, string literals have always been of type const char[n] , at least since the standardization in ‘98.

I think it's perfectly reasonable for them to have different const -ness, because the semantics are completely different:

In the first case, the compiler generates code to copy the contents of the global string literal into a local array. Hence, no const , you can do with it whatever you want, like any other local variable.
  • In the second case, you have a pointer to a global string literal, that is shared with other parts of the code, and is possibly in a section mapped as read-only memory or even in read-only flash. Hence, const , because you absolutely shouldn't write to it.

If you cast away the const in the second case, there is no way to ensure that you (or some library function you call) doesn't try to write to it. The only reason I can see to cast away const is if you have to pass it to some external library. Then either the library does write to that argument, and it's a bug, or the library doesn't write to it, and the argument should have been marked const , in which case, you should fix the function signature, not carelessly cast away const .

Exactly. K&R c did not have const. IIRC, const was added in with the early days of ANSI c++, in the early '90s.

I own a copy of K&C's "The C Programming Language", Secoond Edition, May. 1990. In this book the, const keyword is found at Page-40 (const char msg[] = "warning: ");. (Thee First Edition of the book was in 1978.)

westfw: I'm vaguely annoyed that the type of string literals changed somewhere along the lines.

I don't remember exactly. "Your code can modify literal strings" was one of those legendary warnings passed around, and it was a Big Deal when compilers gained the ability to put literals in the .code segment where they could be protected and/or ROMed. I think that pre-dated either "const" or "literal strings are const" as a compiler feature.

Good point. I was thinking of the global variable case.

Related Topics

IMAGES

  1. Arduino IDE

    error invalid array assignment arduino

  2. 5 Error Arduino dan Cara Mengatasinya

    error invalid array assignment arduino

  3. Fix: Most Common Error Uploading to Arduino or Any Other Board

    error invalid array assignment arduino

  4. Two Ways to Reset Arduino in Software (with Pictures)

    error invalid array assignment arduino

  5. Fix: Arduino error: Was not declared in this scope

    error invalid array assignment arduino

  6. There is no communication of problem when monitor process creation

    error invalid array assignment arduino

VIDEO

  1. 2024 Arduino LCD Assignment Description

  2. Assignment 1

  3. Assignment 2

  4. New arduino nano uploading error problem and Arduino nano drive problem solved (#circuiteffects)

  5. arduino homework assignment

  6. Project Arduino

COMMENTS

  1. Simple word translator, return error: invalid array assignment

    It looks like you're trying to copy the contents of a particular sub-array in dasar across to the output array. However, this isn't valid in C/C++: output[]=dasar[k]; To copy data from one array to another, you either need to copy each element one-by-one (e.g. in a loop), or use a block memory operation like memcpy. Here's how I would do it:

  2. Problem with arrays

    First things first - if all you saving in each element is a 1 or a 0, that's a huge waste of memory. Make the elements "byte" or better still, pack the bits. And post your code - use code tags. Delta_G December 28, 2013, 4:56pm 3. int frase [LETRAS] [8] [8]; frase [0]= M; You've got two dimensions to that array, but you're only specifying one.

  3. To assign a value to an array:

    you can declare an array, which I have done just like the very first example in the link. You can then assign a value to the array. Which I have done as the above link describes in the only method it shows. My code. int myInt[5]; myInt[0] = 1; myInt[1] = 2; myInt[2] = 3; myInt[3] = 4;

  4. c

    prog.cpp:8:9: error: invalid array assignment. c; Share. Improve this question. Follow edited Oct 14, 2015 at 6:32. Haris. 12.2k 6 6 gold badges 45 45 silver badges 74 74 bronze badges. asked Oct 14, 2015 at 6:31. Rohit Mangla Rohit Mangla. 43 1 1 gold badge 1 1 silver badge 3 3 bronze badges.

  5. Arduino: Simple word translator, return error: invalid array assignment

    Arduino: Simple word translator, return error: invalid array assignmentHelpful? Please support me on Patreon: https://www.patreon.com/roelvandepaarWith than...

  6. Assigning an element of a multidimensional array to a second array

    I have two arrays. The first array is a multidimensional array holding color values. The 2nd array stores an active color from the 1st array. ... // error: assigning to an array from an initializer list EXCLUSIVE_COLOR = colors[0]; // error: invalid array assignment array; Share. Improve this question ... Thanks for contributing an answer to ...

  7. Passing array size and values into object made from class

    Now then, progress of making actual class is now this. This is using pointers, but it escapes me why object doesn't get correct size & data passed. class arrayInClass {. public: arrayInClass::arrayInClass(byte* dataArray, byte arraySize, char* arrayName) {. _arraySize = arraySize;

  8. char array help

    char array help - Syntax & Programs - Arduino Forum. Forum 2005-2010 (read only) Software Syntax & Programs. system December 13, 2009, 11:46pm 1. I am fairly new to coding and arduino. I am trying to have arduino write "On" or "Off" to a char variable depending on state of digital out pin. I keep getting invalid array assignment.

  9. arduino ide

    Firstly, arrays in C and C++ are not assignable. So, your attempts to assign something to myData array with = operator are bound to fail in any case. Copying data into naked arrays should be done either manually or using library functions. Secondly, your myData array is declared with size 1. It is just one byte. It is too small to store ...

  10. Multi-dim array assignment

    Hello. I am trying to use a 2D array to have an array of size 5 which holds arrays within. I have a function where i try to move the arrays to the next position: ex: {{7,7,7,7},{4,4,4,4},{2,2,2,2},{3,3,3,3},{5,5,5,5}} after the assignment where i add a new array and move all the others down one place would be: {{8,8,8,8},{7,7,7,7},{4,4,4,4},{2,2,2,2},{3,3,3,3}} but I am having trouble ...

  11. c++

    You can't assign arrays, and . usrname = "User" does just that. Don't. You meant. usrname == "User" which is a comparison, but won't compare your strings. It just compares pointers. Use std::string instead of char arrays or pointers and compare with ==: #include <string> //...

  12. arduino uno

    ‣ array subscript is above array bounds [-Warray-bounds] And of course there is the (somewhat hard to spot - Kudos to Mikael for finding it - it took me a bit to see it myself) naming conflict: ‣ invalid types 'int[int]' for array subscript

  13. Change string

    Instead of using a string literal to initialize, you can make the array any size you want and then strcpy () whatever you want: // Thsee messages can't have more than 14 characters plus terminating zero byte. char msg[15]; . . . strcpy(msg, "Hi, Everyone.");//13 plus terminating zero byte.

  14. arrays

    You can't declare a static array like that, with bounds of x, _y, _z where x, _y, _z are not constants. The array won't redefine its length in the future when you change x, _y, _z. In your constructor you are passing as an argument, a name _x which is also a class variable. C++ doesn't let you assign arrays like this:

  15. Why do I get "invalid operands of types 'const char*'" error?

    This is the error: exit status 1 invalid operands of types 'const char*' and 'const char [2]' to binary 'operator+' Here is the code that triggers it: lcd.print("0"+ ... Thanks for contributing an answer to Arduino Stack Exchange! ... return error: invalid array assignment. 0. Read sensor and convert reading to const char* 1. Error: invalid ...

  16. "Compilation error: assigning to an array from an ...

    Arduino Forum "Compilation error: assigning to an array from an initializer list" When changing values of an array. Using Arduino. Programming Questions. ... Assign new values to the array's elements with individual assignment statements. falcormoor April 4, 2023, 8:34pm 3. is there a more concise way to do that then writing 18 lines? ...

  17. c++

    You say dateAdded is an array of chars - then, at least the following line will fail since temp is declared as string:. dateAdded[count+1] = temp; Use something like. dateAdded[count+1] = temp[0]; Probably it is even better to declare temp as char - there is no reason to use string to temporarily store an element of a char array.

  18. Can't access an array-type member of a structure?

    As with all arrays, it might decay to a pointer when used in an expression, but the string literal itself is an array, not a pointer. [lex.string] An ordinary string literal has type "array of n const char " where n is the size of the string as defined below, has static storage duration (6.7.5), and is initialized with the given characters.

  19. arduino ide

    Thanks for contributing an answer to Arduino Stack Exchange! Please be sure to answer the question. Provide details and share your research! But avoid … Asking for help, clarification, or responding to other answers. Making statements based on opinion; back them up with references or personal experience.

  20. c++

    1. Use char* aux; instead. When we write char aux [50];, we are immediately allocating memory for ~50 char s. Here you're only swapping pointers to the char arrays (elements in the array of char array, i.e. 2D char array called name ), so a char* is what you're looking for. If you are okay with using the standard library, use std::swap like so: