Go Down

Topic: Somewhat strange way of programming observed in arduino avr core (Read 462 times) previous topic - next topic

liuzengqiang

Been digging into USB stuff for a few days. I keep seeing some strange things like #define and magic numbers coexist. This following one is a new discovery. Hope someone can justify its existence.:

USBCore.cpp in arduino's avr core folder:

Code: [Select]
//Line 45 in IDE 1.8.4
#ifndef USB_PRODUCT
// If no product is provided, use USB IO Board
#define USB_PRODUCT     "USB IO Board"
#endif

const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT;

So we know USB_PRODUCT is a def and STRING_PRODUCT is a PROGMEM C-string defined by STRING_PRODUCT, only residing in PROGMEM.

Code: [Select]
// Line 524 in IDE 1.8.4
return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM);

Since we know STRING_PRODUCT is a PROGMEM C-string, we CAN'T use strlen() on it. We must find its length to make the call! Since USB_PRODUCT is a def, we CAN use strlen on it, or rather, on the string literal created by its def.

Instead of using the proper strlen_P(), a literal string was defined and used once (yes, discarded from stack, I get it), just so that the developer CAN call strlen() on it. What a load of non-sense or am I missing something?
Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter

Juraj

strlen(USB_PRODUCT) is evaluated by the compiler, not in runtime

liuzengqiang

strlen(USB_PRODUCT) is evaluated by the compiler, not in runtime
Any reference to this claim? I'd like to confirm it if possible. This means it costs no time to do this, which seems a good reason. I thought this instantiates an unnamed string literal and then call strlen() to return its length. Thanks.
Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter

Juraj

Any reference to this claim? I'd like to confirm it if possible. This means it costs no time to do this, which seems a good reason. I thought this instantiates an unnamed string literal and then call strlen() to return its length. Thanks.
it works :-)

Juraj

Arduino has compiler option -Os

    Optimize for size. -Os enables all -O2 optimizations except those that often increase code size:

-O2 includes -foptimize-strlen

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

liuzengqiang

Figured out a simple test:
Code: [Select]

void setup() {
  // put your setup code here, to run once:
  int a=25;
}

void loop() {
  // put your main code here, to run repeatedly:

}


Compilation:
Code: [Select]

Sketch uses 450 bytes (1%) of program storage space. Maximum is 32,256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes.

Code: [Select]

const char str25[]="0123456789012345678901234";
void setup() {
  // put your setup code here, to run once:
  int a=strlen(str25);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Compilation:
Code: [Select]

Sketch uses 450 bytes (1%) of program storage space. Maximum is 32,256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes.

So there is no difference. Thus this means you are perfectly right Sir/Mam! Thank you!
Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter

Juraj

So there is no difference. Thus this means you are perfectly right Sir/Mam! Thank you!
https://en.wikipedia.org/wiki/Juraj

liuzengqiang

Serial LCD keypad panel,phi_prompt user interface library,SDI-12 USB Adapter

Go Up