Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

246
Vistas
Concatenate compile time constant strings with characters whose character code comes from a #define

I want to assemble a char array that contains one byte with a compile time constant value and a string, which is also compile time constant. Solution would be:

char packet[] = "\x42" __DATE__;

That works but is not very readable and maintainable, as that 0x42 is a message opcode that is used elsewhere, making this a magic number. Now, I could put a dummy x into the string and follow this definition with an assignment like this:

#define OPCODE 0x42
char packet[] = "x" __DATE__;
packet[0] = OPCODE;

But I have the feeling that could be done in a purely constant string literal, I just can't find how to do it. Any idea?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

__DATE__ should mostly have exactly Mmm dd yyyy format, so 11 characters. You can do this:

char packet[] = {
  OPCODE,
  __DATE__[0],
  __DATE__[1],
  __DATE__[2],
  __DATE__[3],
  __DATE__[4],
  __DATE__[5],
  __DATE__[6],
  __DATE__[7],
  __DATE__[8],
  __DATE__[9],
  __DATE__[10],
  __DATE__[11],
  0,
};
   
over 4 years ago · Santiago Trujillo Denunciar

0

As the C preprocessor cannot help here, this might be a case for an additional preprocessor to be added to the build system.

Whether you choose a second stage of C preprocessor, m4, a shell or python script or whatever else is up to you.

Or you go another route and change the packet type from char array to a struct with a flexible array member, something like the following:

/* foo.c
 * Compile with something like
 *    avr-gcc -mmcu=atmega328 -Os -Wall -Wextra -Werror \
 *        -save-temps=obj -Wa,-adhlns=foo.lst,-gstabs -c foo.c
 */

#include <stddef.h>
#include <stdint.h>

#include <avr/pgmspace.h>

#define OPCODE_DATE 0x42

struct packet_descr {
  uint8_t  opcode;
  uint16_t size;
};

struct string_packet {
  struct packet_descr descr;
  char                string[];
};

#define STRING_PACKET_P(IDENTIFIER, OPCODE, STRING)   \
  const struct string_packet IDENTIFIER PROGMEM = {   \
    { (OPCODE),                                       \
      sizeof(STRING)-1                                \
    },                                                \
    (STRING)                                          \
  }

STRING_PACKET_P(packet_date_P, OPCODE_DATE, __DATE__);

void uart_send_char(const char ch);
void uart_send_char(const char ch)
{
  UDR0 = ch;
}

/* Send string packet in the following format:
 *      uint8_t  opcode;
 *      uint16_t len;         // in AVR endianness
 *      char     string[len]; // string of "len" characters, unterminated
 */
extern
void string_packet_send_P(const struct string_packet *string_packet_P);
void string_packet_send_P(const struct string_packet *string_packet_P)
{
  const uint8_t opcode = pgm_read_byte(&string_packet_P->descr.opcode);
  uart_send_char(opcode);

  size_t        len    = pgm_read_word(&string_packet_P->descr.size);
  for (PGM_P byte_P = (PGM_P)&string_packet_P->string; len > 0; len--, byte_P++) {
    uart_send_char(pgm_read_byte(byte_P));
  }
}

int main(void)
{
  string_packet_send_P(&packet_date_P);
  return 0;
}

One obvious disadvantage of a struct with a flexible array member is that sizeof(packet) will only yield the size of the non-array part. However, depending on your actual packet format (the receiver of the packet also needs to know when a packet starts and finishes, right?), recording the size separately might be feasible.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda