------- Comment #6 from j at uriah dot heep dot sax dot de 2007-11-15 21:21 ------- I'm not sure whether this is related or not... but from the description, it looks so.
avr-libc contains a macro that helps the users declaring a flash-ROM string, lacking any real support in GCC for different memory sections (as proposed by the Embedded C draft). This works by using the GCC extension that a block can return a value: a block is openened, and a block-scope static variable is allocated, using the string literal passed in by the user. Then, that block returns the address of this variable to the caller. By giving the block-scope variable the "progmem" attribute, it will eventually be allocated in ROM rather than RAM. Now, if that macro is called with identical string literals within one translation unit, the strings are allocated separately rather than merged into a single location. This behaviour is reproducable as well on the i386 target, so it looks like not really related to the avr backend. Here's a simple test case. For simplicity, the original PSTR() macro is just reproduced in the file rather than including the entire original header(s). #if defined(__AVR__) # define PROGMEM __attribute__((__progmem__)) #else # define PROGMEM /* nothing */ #endif #define PSTR(x) \ (__extension__({static const char __c[] PROGMEM = (x); &__c[0];})) extern void puts_P(const char *); void dosomething(void) { puts_P(PSTR("Hello world!")); puts_P(PSTR("Hello world!")); } Compiling for the avr target yields: .file "foo.c" __SREG__ = 0x3f __SP_H__ = 0x3e __SP_L__ = 0x3d __tmp_reg__ = 0 __zero_reg__ = 1 .global __do_copy_data .global __do_clear_bss .text .global dosomething .type dosomething, @function dosomething: /* prologue: frame size=0 */ /* prologue end (size=0) */ ldi r24,lo8(__c.1471) ldi r25,hi8(__c.1471) rcall puts_P ldi r24,lo8(__c.1473) ldi r25,hi8(__c.1473) rcall puts_P /* epilogue: frame size=0 */ ret /* epilogue end (size=1) */ /* function dosomething size 7 (6) */ .size dosomething, .-dosomething .section .progmem.data,"a",@progbits .type __c.1473, @object .size __c.1473, 13 __c.1473: .string "Hello world!" .type __c.1471, @object .size __c.1471, 13 __c.1471: .string "Hello world!" /* File "foo.c": code 7 = 0x0007 ( 6), prologues 0, epilogues 1 */ Compiling the same file for the i386 target also shows two copies of the string literal: .file "foo.c" .section .rodata .type __c.0, @object .size __c.0, 13 __c.0: .string "Hello world!" .type __c.1, @object .size __c.1, 13 __c.1: .string "Hello world!" .text .globl dosomething .type dosomething, @function dosomething: pushl %ebp movl %esp, %ebp pushl $__c.0 call puts_P movl $__c.1, (%esp) call puts_P leave ret .size dosomething, .-dosomething .ident "GCC: (GNU) 3.4.4 [FreeBSD] 20050518" -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21018