2

The following code is compiled and linked for a DSP target processor:

Test.c:

static q32 a[15] = { 
                          Q31(0.1f),Q31(0.2f),Q31(0.3f),Q31(0.4f),Q31(0.5f),
                          Q31(0.1f),Q31(0.2f),Q31(0.3f),Q31(0.4f),Q31(0.5f),
                          Q31(0.1f),Q31(0.2f),Q31(0.3f),Q31(0.4f),Q31(0.5f)
                        };

static int b[3] = { 1, 1, 0 };

int main() 
{
   // ... 
   return 0;
}

q32 is a fixed point type, 4 bytes.

After I link the code, the .map file tells me the following: Test.o: .bss 60, .data 12.

Why does a (60 bytes) end up in .bss section, and b (12 bytes) in .data section? I would expect both to go into .data.

Danijel
  • 8,198
  • 18
  • 69
  • 133
  • `a[15]` ints 4-bytes each = 60-bytes in Block Started by Symbol. – David C. Rankin Feb 12 '18 at 08:43
  • How is `Q31` defined? – Matthias Feb 12 '18 at 08:51
  • Q31 is a macro that converts float to [fixed point Q number](https://en.wikipedia.org/wiki/Q_(number_format)). It'se defined as `#define Q31(x) ((q32)(int)((double)(x)*(double)0x80000000UL`. – Danijel Feb 12 '18 at 08:55
  • You have to provide the definition of `q32` and also more context. Please state the exact target and tool chain used. All we can do with this is to tell you "this seems wrong", which you already figured out yourself. – Lundin Feb 12 '18 at 08:57
  • @DavidC.Rankin `.bss` is defined as: "data segment containing statically-allocated variables that are not explicitly initialized to any value". Both arrays are initialized, so they should not go to `.bss`? – Danijel Feb 12 '18 at 08:57
  • @Danijel: No, its still uninitialized, because the macro isn't processed at compiling. So that will take the whole array of 15 in .bss – WedaPashi Feb 12 '18 at 09:00
  • @WedaPashi When is the macro computed then if not at compile time? – Danijel Feb 12 '18 at 09:16
  • 1
    @WedaPashi If the macro isn't a constant expression processed at compile-time, the code will not compile. – Lundin Feb 12 '18 at 09:38
  • 1
    Whether or not an expression with constant terms gets evaluated by the compiler at compile time is an implementation detail. Generally, the more convoluted the lower the odds. Just look at the assembly listing, you ought to easily to find the machine code back. – Hans Passant Feb 12 '18 at 10:25

3 Answers3

1

Thats how .bss is supposed to be used. Since its supposed to represent uninitialized data (I didn't say that it holds the uninitialized variables!), Lets just say that BSS segment only holds variables that don't have any value yet, so it doesn't actually need to store these variables. So, BSS is an optimization such that the object file will only hold a single value, lets say the space required of the variables for now. Which is 15 * 4 = 60.

Wiki says,

The size that BSS will require at runtime is recorded in the object file, but BSS (unlike the data segment) doesn't take up any actual space in the object file.

Thats one way to make your executable smaller in size.

Now, Since Q31 is a macro that expands to ((q32)(int)((double)(x)*(double)0x80000000UL, Q31(1.0f) will still obviously be not understandable at compile-time. So, it is treated as uninitialized, So that goes into .bss.

Although, ((q32)(int)((double)(x)*(double)0x80000000UL is known to be a fixed constant expression.

Try putting fixed values, and you should see them in .data segment.

Anyway once the program loading is done, it doesn't matter in what segment it was.

WedaPashi
  • 3,561
  • 26
  • 42
  • The problem with this reasoning is that an array initializer list of an object with static storage duration must consist only of constants or constant expressions. Otherwise the code will not compile. Are you implying that the OP's system is using some non-standard extension to C? – Lundin Feb 12 '18 at 09:40
  • Yes, but I am not certain. I can't see the other reason to it. – WedaPashi Feb 12 '18 at 09:43
  • @Danijel: You are the better judge and I am okay with whatever you decide, its your question :-) – WedaPashi Feb 20 '18 at 12:44
0

In some Q-something-formats the integer part is fixed assigned to 1 or 0. In case, the first is true for your format, q32 consists of zero-bytes only. The bbs segment is initialised with zero at startup time. Thus, placing q32 in bbs avoids some initialisation data.

Matthias
  • 8,018
  • 2
  • 27
  • 53
0

uninitialized global will goes into .bss section and global with some intial value goes to .data section. if you have global variable with ititial value as 0(zero) then it will goes into .bss section as way of optimizing size of final binary.see if your Q31(1.0f) resolve to value 0, if its the case than above is the reason for a[15] going into .bss section instead of .data