initializing const char array

Hi all -

This isn't purely a C++ problem, but it could arise in a C++ program.

I'm working on a firmware app. A library uses a struct with a const char array member. My question is, how do I initialize that member?

Here's what I'm trying to do:

typedef struct httpd_req {
const char uri[HTTPD_MAX_URI_LEN + 1];
...
} httpd_req_t;

static char buff[513];
uri_decode(req->uri, strlen(req->uri), buff);
httpd_req_t newReq = {
.uri = buff,
...
}

but I get a couple errors, about missing braces, and initializing a char from a char *. Can someone tell me what I'm doing wrong?

Thanks...
You can't use = to copy C-style arrays like that. I don't see a way to keep it as a const array, if buff contains runtime data.

If you're willing to use std::array, you can achieve this because std::arrays let you use =.

Edit: I see your below post, but just to show you want I'm talking about in case others are interested
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <array>

const int HTTPD_MAX_URI_LEN = 100; // dummy value

typedef struct httpd_req {
    const std::array<char, HTTPD_MAX_URI_LEN + 1> uri;
} httpd_req_t;

void uri_decode_dummy(char* buffer, int length)
{
    buffer[0] = '4';
    buffer[1] = '2';
    buffer[2] = '\0'; // dummy data
}

int main()
{
    std::array<char, HTTPD_MAX_URI_LEN + 1> buff;
    uri_decode_dummy(&buff[0], HTTPD_MAX_URI_LEN + 1);
 
    httpd_req_t newReq = {
        .uri = buff,
    };
    
    std::cout << newReq.uri.data() << '\n';
}
Last edited on
Hi Ganado -

Unfortunately, the struct definition is part of the SDK. I really don't know how that field gets initialized. I guess I could do a memcpy over the entire struct, but that's not a very clean solution.
I'm guessing this must be some sort of compiler extension, unless somebody else has a better idea. Your code is very C-like, not C++-like. Do you know what compiler this SDK recommends, and do you have any links to documentation for this SDK?

Edit: Actually there might be a way to this. I'm trying something out. I would still like a link to the documentation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <cstring>

const int HTTPD_MAX_URI_LEN = 100; // dummy value

typedef struct httpd_req {
    const char uri[HTTPD_MAX_URI_LEN + 1];
} httpd_req_t;

typedef struct my_httpd_req {
    char uri[HTTPD_MAX_URI_LEN + 1];
} my_httpd_req_t;


void uri_decode_dummy(char* output)
{
    output[0] = '4';
    output[1] = '2';
    output[2] = '\0'; // dummy data
}

int main()
{
    static char buff[513];
    uri_decode_dummy(buff);
    
    my_httpd_req myNewReq;
    strcpy(myNewReq.uri, buff);
    
    httpd_req_t newReq = *(httpd_req_t*)(&myNewReq);
    
    std::cout << newReq.uri << '\n';
}


Simpler main:
1
2
3
4
5
6
7
8
9
int main()
{
    my_httpd_req myNewReq;
    uri_decode_dummy(myNewReq.uri);
 
    httpd_req_t newReq = *(httpd_req_t*)(&myNewReq);
    
    std::cout << newReq.uri << '\n';
}


I don't know if this is technically legal. I think it is. Maybe an expert can comment. But it works.

PS: In C++ you don't actually need to do the weird 'typedef' hack. You can use the struct name directly.
Last edited on
Hi Ganado -

Your observation about this being C-like is spot-on. I only asked here because this forum seems to know the answer to just about everything.

The SDK is really the Espressif IDF. They use a compiler for the xtensa architecture, but I don't think they added any functionality that would cover this oddity.
Okay, thanks. But before we go digging into that, I think my struct casting bypasses the issue of the const array. You should try it out at some point and let us know if it works.

The two key points are:

1
2
3
typedef struct my_httpd_req {
    char uri[HTTPD_MAX_URI_LEN + 1];
} my_httpd_req_t;

This is byte-wise the same as the httpd_req_t struct, but not const.

1
2
3
    my_httpd_req_t myNewReq;
    // ... fill myNewReq with data ...
    httpd_req_t newReq = *(httpd_req_t*)(&myNewReq)

This then reinterprets the my_httpd_req_t object as a httpd_req_t object.
Last edited on
Have you considered using the manufacturers forums for answers to your questions?


Also most embedded processor companies have data sheets available for their different processors that sometimes contain sample code that may be similar to what you are trying to do.

https://www.espressif.com/en/support/documents/technical-documents


Without knowing the exact piece of hardware and the exact processor it is going to be hard to give solid answers, will also need to know your build system OS.

Hi jlb -

I will indeed use the mfg. forum for this; I just thought I'd try here first.

FWIW, I'm 99% sure that this isn't some special feature they built into their compiler. It *could* be part of their build system, but I doubt that as well. I've looked through the source for their IDF and can't find an instance of where they populate this struct...really weird.
You're really not providing enough information to get any meaningful answers.


but I get a couple errors, about missing braces, and initializing a char from a char *. Can someone tell me what I'm doing wrong?


You need to post the complete error/warning messages, exactly as shown in the development environment. Compiler error messages usually have important information embedded within the text so you need to show the complete error message (all of them since one problem can generate multiple error messages).

You are also not providing near enough code, on something like this you would probably be better off posting the smallest possible complete program that illustrates the problem.

FWIW, I'm 99% sure that this isn't some special feature they built into their compiler.

Actually I would disagree. This code appears to be part of an HTTP: service which while not really "special" it is a feature of the SDK, not necessarily a compiler feature.

By the way searching for "httpd_req_t" with my search engine I came across this page:
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/protocols/esp_http_server.html

Which contains a good piece of example code that you can probably modify to do exactly what you need.

Topic archived. No new replies allowed.