llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Rohan A M (badwriter123) <details> <summary>Changes</summary> This commit adds comprehensive documentation and test coverage for a common C programming error: 'incompatible pointer to integer conversion initializing const char with an expression of type char[N]'. Added files: - clang/test/Sema/array-init-pointer-conversion.c: Test cases demonstrating the error and correct solutions - clang/docs/array-init-common-errors.md: Comprehensive documentation explaining the error and multiple solution approaches - clang/examples/array-init-solutions.c: Working examples showing best practices for array initialization The error commonly occurs when developers try to initialize an array of single characters (const char[]) with string literals, when they actually need an array of string pointers (const char*[]). This documentation will help developers understand: - Why the error occurs - Multiple correct approaches to fix it - Best practices for different use cases - Real-world examples with compound literals Fixes a gap in documentation for this frequent C programming mistake. --- Full diff: https://github.com/llvm/llvm-project/pull/154061.diff 3 Files Affected: - (added) clang/docs/array-init-common-errors.md (+101) - (added) clang/examples/array-init-solutions.c (+85) - (added) clang/test/Sema/array-init-pointer-conversion.c (+48) ``````````diff diff --git a/clang/docs/array-init-common-errors.md b/clang/docs/array-init-common-errors.md new file mode 100644 index 0000000000000..127e8e49567a8 --- /dev/null +++ b/clang/docs/array-init-common-errors.md @@ -0,0 +1,101 @@ +# Common Array Initialization Errors in C + +## Incompatible Pointer to Integer Conversion Error + +### Problem Description + +A common error when working with array initialization in C is: +``` +error: incompatible pointer to integer conversion initializing 'const char' +with an expression of type 'char[N]' [-Wint-conversion] +``` + +This error occurs when you try to initialize an array of single characters (`const char[]`) with string literals. + +### Common Mistake + +```c +// ❌ WRONG - This causes the error +const char *msg = (const char[]) { + [0] = "Success", // ERROR! String literal to single char + [1] = "Failed" // ERROR! String literal to single char +}[0]; +``` + +### The Problem + +- `const char[]` declares an array of single characters +- `"Success"` is a string literal (array of characters) +- You cannot assign an array to a single character element + +### Correct Solutions + +#### Solution 1: Array of String Pointers +```c +// ✅ CORRECT - Array of pointers to strings +const char *msg = (const char*[]) { + [0] = "Success", + [1] = "Failed", + [2] = "Pending" +}[code]; +``` + +#### Solution 2: Array of Single Characters +```c +// ✅ CORRECT - If you actually want single characters +const char chars[] = { + [0] = 'S', // Single character literals + [1] = 'F', + [2] = 'P' +}; +``` + +#### Solution 3: 2D Character Array +```c +// ✅ CORRECT - Array of character arrays +const char strings[][10] = { + [0] = "Success", + [1] = "Failed", + [2] = "Pending" +}; +``` + +#### Solution 4: Direct Declaration +```c +// ✅ CORRECT - Simple string pointer array +const char *messages[] = { + [0] = "Success", + [1] = "Failed", + [2] = "Pending" +}; +``` + +### Key Differences + +| Declaration | Type | Usage | +|-------------|------|-------| +| `const char[]` | Array of single chars | For individual characters | +| `const char*[]` | Array of string pointers | For string messages | +| `const char[][N]` | 2D char array | For fixed-length strings | + +### Real-World Example Fix + +```c +// Before (causes error): +_Noreturn void handle_error(int code) { + const char *msg = (const char[]) { // ❌ Wrong type + [0] = "Success", + [1] = "General error" + }[code]; +} + +// After (fixed): +_Noreturn void handle_error(int code) { + const char *msg = (const char*[]) { // ✅ Added asterisk + [0] = "Success", + [1] = "General error" + }[code]; +} +``` + +The fix is simple: change `const char[]` to `const char*[]` to indicate an array of string pointers instead of an array of single characters. \ No newline at end of file diff --git a/clang/examples/array-init-solutions.c b/clang/examples/array-init-solutions.c new file mode 100644 index 0000000000000..25c350c0b1511 --- /dev/null +++ b/clang/examples/array-init-solutions.c @@ -0,0 +1,85 @@ +// Example demonstrating correct array initialization patterns +// This file compiles without errors and shows best practices + +#include <stdio.h> +#include <stdlib.h> + +// Example 1: Error handling with string messages +_Noreturn void handle_error(int code) { + // ✅ CORRECT: Array of string pointers using compound literal + const char *msg = (const char*[]) { + [0] = "Success", + [1] = "General error", + [2] = "Invalid input", + [3] = "Memory allocation failed" + }[code]; + + fprintf(stderr, "Error: %s (%d)\n", msg ? msg : "Unknown", code); + exit(code); +} + +// Example 2: Status codes with different approaches +void demonstrate_array_patterns() { + // Pattern 1: Direct string pointer array + const char *status_messages[] = { + [0] = "Ready", + [1] = "Processing", + [2] = "Complete", + [3] = "Error" + }; + + // Pattern 2: 2D character array for fixed-length strings + const char status_codes[][12] = { + [0] = "READY", + [1] = "PROCESSING", + [2] = "COMPLETE", + [3] = "ERROR" + }; + + // Pattern 3: Single character codes (when you actually want chars) + const char single_chars[] = { + [0] = 'R', // Ready + [1] = 'P', // Processing + [2] = 'C', // Complete + [3] = 'E' // Error + }; + + // Usage examples + printf("Message: %s\n", status_messages[1]); + printf("Code: %s\n", status_codes[1]); + printf("Char: %c\n", single_chars[1]); +} + +// Example 3: Dynamic message selection +const char* get_http_status_message(int code) { + // ✅ CORRECT: Compound literal with string pointers + return (const char*[]) { + [200] = "OK", + [404] = "Not Found", + [500] = "Internal Server Error" + }[code]; +} + +// Example 4: Initialization in function parameters +void log_message(int level) { + // ✅ CORRECT: Inline compound literal + printf("[%s] Message logged\n", + (const char*[]) { + [0] = "DEBUG", + [1] = "INFO", + [2] = "WARN", + [3] = "ERROR" + }[level]); +} + +int main() { + demonstrate_array_patterns(); + log_message(1); + + const char* http_msg = get_http_status_message(404); + if (http_msg) { + printf("HTTP Status: %s\n", http_msg); + } + + return 0; +} \ No newline at end of file diff --git a/clang/test/Sema/array-init-pointer-conversion.c b/clang/test/Sema/array-init-pointer-conversion.c new file mode 100644 index 0000000000000..4dc126da9c1b3 --- /dev/null +++ b/clang/test/Sema/array-init-pointer-conversion.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// Test for "incompatible pointer to integer conversion" error when initializing +// const char arrays with string literals in designated initializers + +void test_array_initialization_errors() { + // ❌ ERROR: Trying to initialize array of single chars with string literals + const char *msg1 = (const char[]) { + [0] = "Success", // expected-error {{incompatible pointer to integer conversion initializing 'const char' with an expression of type 'char[8]'}} + [1] = "Failed" // expected-error {{incompatible pointer to integer conversion initializing 'const char' with an expression of type 'char[7]'}} + }[0]; // expected-error {{incompatible integer to pointer conversion initializing 'const char *' with an expression of type 'const char'}} + + // ❌ ERROR: Same issue with regular array initialization + const char error_array[] = { + [0] = "Success", // expected-error {{incompatible pointer to integer conversion initializing 'const char' with an expression of type 'char[8]'}} + [1] = "Failed" // expected-error {{incompatible pointer to integer conversion initializing 'const char' with an expression of type 'char[7]'}} + }; +} + +void test_correct_solutions() { + // ✅ CORRECT: Array of string pointers + const char *msg1 = (const char*[]) { + [0] = "Success", + [1] = "Failed", + [2] = "Pending" + }[0]; // expected-no-diagnostics + + // ✅ CORRECT: Array of single characters + const char char_array[] = { + [0] = 'S', // Single character literals + [1] = 'F', + [2] = 'P' + }; // expected-no-diagnostics + + // ✅ CORRECT: 2D character array (array of character arrays) + const char string_array[][10] = { + [0] = "Success", + [1] = "Failed", + [2] = "Pending" + }; // expected-no-diagnostics + + // ✅ CORRECT: Direct string pointer array declaration + const char *messages[] = { + [0] = "Success", + [1] = "Failed", + [2] = "Pending" + }; // expected-no-diagnostics +} \ No newline at end of file `````````` </details> https://github.com/llvm/llvm-project/pull/154061 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits