Compilation (gcc error)Type & Declaration7 min read

Assignment to Expression with Array Type in C: Why It Fails

In C, an array is not a modifiable lvalue, so you cannot assign a new string or another array to it with = after declaration. Initialize the array when you declare it, copy elements into its existing storage, or use a pointer when you actually need to select a different string. This is a compile-time constraint, not a segmentation fault.

Quick Fix Summary

Use char name[16] = "Alice"; at declaration, or snprintf(name, sizeof name, "%s", source) afterward. Check the return value for failure or truncation. Only use strcpy when the destination is large enough for the source and its terminating null byte.

Fixed-address C char array rejecting direct '=' assignment vs copying bytes into the buffer with snprintf or strcpy.
Fixed-address C char array rejecting direct '=' assignment vs copying bytes into the buffer with snprintf or strcpy.

Why This Error Happens

Initialization is not assignment

char name[16] = "Alice"; initializes the array elements. The same text after a separate declaration, name = "Alice";, attempts array assignment and is invalid. An array owns contiguous element storage for its lifetime; it is not a pointer variable that can be redirected. Although array expressions commonly convert to a pointer to the first element, that conversion does not create an assignable array object.

Choose the operation that matches your data

For a C string, reserve room for the terminating \0. snprintf takes a capacity and writes at most capacity minus one characters when capacity is nonzero; a negative return means an encoding/output error, and a return greater than or equal to capacity means truncation. Use a literal format such as "%s" rather than treating user text as the format. strcpy copies through the terminator but has no capacity parameter: verify strlen(source) < capacity first. Neither function permits overlapping source and destination.

Numeric arrays and overlapping copies

memcpy(destination, source, sizeof destination) can copy a complete equal-sized numeric array when both ranges are valid and do not overlap. If they overlap, use memmove. Do not use strcpy for integer arrays or arbitrary binary data. Inside a function parameter declared char destination[], the parameter is adjusted to a pointer; sizeof destination measures that pointer, not the caller's buffer. Pass the capacity explicitly.

Pointer reassignment is a different design

const char *name = "Alice"; name = "Bob"; changes which string a pointer denotes. It does not copy characters. Do not write through a pointer to a string literal. For writable text use an actual character array or suitably allocated storage. A structure containing an array member can be assigned as a whole compatible structure; its array member still cannot be assigned separately.

Top Root Causes & Specific Code Fixes

String assigned after declaration

Move the literal into the initializer, or copy into the allocated buffer with an explicit capacity.

Broken Pattern
char name[16];
name = "Alice";
Corrected Pattern
char name[16] = "Alice";
Illustrative diagnostic (not executed):error: assignment to expression with array type

One numeric array assigned to another

Copy elements or a validated byte range. This fragment assumes both arrays are complete objects in the same scope and includes string.h.

Broken Pattern
int a[3] = {1, 2, 3};
int b[3];
b = a;
Corrected Pattern
int a[3] = {1, 2, 3};
int b[3];
memcpy(b, a, sizeof b);

An array member treated as a pointer

Assign the entire structure when appropriate, or copy to the member after checking its capacity. Declaring a pointer instead changes ownership and lifetime responsibilities.

Broken Pattern
struct User { char name[16]; };
struct User u;
u.name = "Alice";
Corrected Pattern
struct User { char name[16]; };
struct User u = { .name = "Alice" };

Complete Broken and Corrected Programs

Compare the source before running it. The broken program is intentionally incorrect; its behavior can depend on the compiler and platform.

Read the broken program
int main(void) {
    char name[16];
    name = "Alice";
    return 0;
}
Open broken program in compiler
Read the corrected program
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char name[16];
    const char *source = "Alice";
    int needed = snprintf(name, sizeof name, "%s", source);
    if (needed < 0 || (size_t)needed >= sizeof name) {
        fputs("Name could not be copied completely\n", stderr);
        return EXIT_FAILURE;
    }
    printf("Name: %s\n", name);
    printf("Capacity: %zu bytes\n", sizeof name);
    return EXIT_SUCCESS;
}
Open corrected program in compiler

Expected output from the corrected program

Reference output, not a live execution result.

Name: Alice
Capacity: 16 bytes

Debugging Techniques and Commands

GCC constraint checks
gcc -std=c17 -Wall -Wextra -Wpedantic main.c -o app

Fix the array assignment before investigating runtime behavior; this program cannot compile as written.

Copy boundary review
gcc -std=c17 -g -fsanitize=address,undefined main.c -o app

After fixing compilation, use sanitizers locally to exercise copy boundaries. Sanitizer availability depends on the compiler environment.

Frequently Asked Questions

Why can I initialize a char array but not assign a string later?

Initialization sets the elements of a newly declared object. Assignment requires a modifiable lvalue, and an array does not qualify; later changes must write individual elements or use a copy operation.

Should I use strcpy or snprintf?

Use strcpy only after proving the source plus terminator fits and the ranges do not overlap. snprintf accepts a capacity but can truncate, so check both negative returns and returns greater than or equal to the capacity.

Does strncpy always make a safe string?

No. If the source length reaches the limit, strncpy does not append a terminating null byte. It also pads short sources. Prefer a deliberately checked string-copy policy instead of assuming its name guarantees safety.

Can a structure containing an array be assigned?

Yes. Whole-structure assignment copies the members, including array members. Assigning directly to an array member remains invalid.

Related errors