How much space the variable takes up depends on what factors

Thread Starter

King2

Joined Jul 17, 2022
163
I understand that to store the value of a variable in a C program we have to declare the variable and assign its value with it.

These four doubts are not clear to me Even after reading

  1. Does only compiler decide how much space the variable will occupy?

  1. Does only targeting system decide how much space the variable will occupy?

  1. Does both compiler and targeting system decide how much space the variable will occupy?

  1. Does the C standard specify how much memory a variable will occupy
 

Papabravo

Joined Feb 24, 2006
21,159
On a given machine with a given compiler, a declaration for a numerical quantity cannot and should not be ambiguous. In particular it should be able to contain the expected range of values. It might be able to contain more but you cannot and should not depend on this. For example, on a machine that can only fetch and store one word of 64 bits at a time each unsigned char could be mapped into a single word.

To answer the questions:
  1. Does only compiler decide how much space the variable will occupy?
    No, the compiler only determines the range of values and the interpretation of those values.
  2. Does only targeting system decide how much space the variable will occupy?
    Yes, the targeting system can employ any method that accommodates the range of values and behaviors required by the compiler definition.
  3. Does both compiler and targeting system decide how much space the variable will occupy?
    No, only the targeting system define how much actual storage a variable will occupy.
  4. Does the C standard specify how much memory a variable will occupy
    In the sense that the standard specifies a range and an interpretation of the values within the range it specifies the minimum required space. A given target machine is allowed to use more than the minimum if that is convenient.
 

nsaspook

Joined Aug 27, 2009
13,087
You can also use the 'sizeof' command/macro to return the number of bytes used. In fact, using that in allocations adds portability to your code.
Be careful with that on data structures as there are no guarantees on sizes because of padding or byte alignment issues that are compiler and hardware dependent.

C:
typedef union
  {
     uint8_t        u8Byte;           ///< REG_8 as unsigned byte
     int8_t         i8Byte;           ///< REG_8 as signed byte
     struct
     {
        unsigned b0:1;                ///< Bit 0 of REG_8 type
        unsigned b1:1;                ///< Bit 1 of REG_8 type
        unsigned b2:1;                ///< Bit 2 of REG_8 type
        unsigned b3:1;                ///< Bit 3 of REG_8 type
        unsigned b4:1;                ///< Bit 4 of REG_8 type
        unsigned b5:1;                ///< Bit 5 of REG_8 type
        unsigned b6:1;                ///< Bit 6 of REG_8 type
        unsigned b7:1;                ///< Bit 7 of REG_8 type
     };
  } REG_8;
sizeof(REG_8) could return 2 instead of the expected 1 if we have 16-bit default strict data-alignment addressing.

https://www.microchip.com/forums/m1074213.aspx
http://www.catb.org/esr/structure-packing/#_structure_alignment_and_padding
 
Last edited:

neanderman

Joined Aug 23, 2022
5
Be careful with that on data structures as there are no guarantees on sizes because of padding or byte alignment issues that are compiler and hardware dependent.

sizeof(REG_8) could return 2 instead of the expected 1 if we have 16-bit default strict data-alignment addressing.
Good point as far as just querying the size, but when allocating space, that's what you'd want.
 

nsaspook

Joined Aug 27, 2009
13,087
Good point as far as just querying the size, but when allocating space, that's what you'd want.
I'm saying you need to aware of that allocation (that by default usually picks the most efficient size manner for the C abstract machine instead of strict binary compatibility) if you are doing low-level embedded programming with hardware register interfaces that are bit to byte to word aligned using C structure/union abstractions. It might be what you'd want if you don't care about I/O memory mapped specific details or specific binary transmission details between x-bit processor types, devices or even different compilers of the same machine architecture.
 
Last edited:

WBahn

Joined Mar 31, 2012
29,979
I understand that to store the value of a variable in a C program we have to declare the variable and assign its value with it.

These four doubts are not clear to me Even after reading

  1. Does only compiler decide how much space the variable will occupy?

  1. Does only targeting system decide how much space the variable will occupy?

  1. Does both compiler and targeting system decide how much space the variable will occupy?

  1. Does the C standard specify how much memory a variable will occupy
Strictly speaking, the C compiler makes that determination. For SOME data types, the C standard specifies it, but for others (particularly the original data types), the size is implementation-specified with the standard placing constraints on the minimum requirements that must be met. There are a lot of macro constants in files such as limits.h and float.h that will let your program respond to what those limits were when the program was compiled.

A question you didn't ask is whether the programmer can specify how much space the variable will occupy. In the newer standards (C99 is when it came in, IIRC) there is a header file with fixed size data types, (e.g., uint16) that are essentially aliases to that implementation's data types of the appropriate size.
 

Thread Starter

King2

Joined Jul 17, 2022
163
char type store character, string but it also store decimal value

When we declare float type, compiler allocate memory. Why float only store floating value like 1.2, 33.2. Why it doesn't store character,

experimented with code
C:
#include<stdio.h>

int main ()
{
    int a = 1;
    int b = 'K';
    char c = 1;
    float d = 12.3;
    float f = "A";

    printf("a = %d \n", a);
    printf("b = %d \n", b);
    printf("b = %c \n", b);
    printf("f = %f \n", f);

    return 0;
}
compiler error
C:
c|10|error: incompatible types when initializing type 'float' using type 'char *'|
 

WBahn

Joined Mar 31, 2012
29,979
char is simply an integer data type. It is required to be at least eight bits and store at least all non-negative integers less than 128.

It can NOT hold a string. In fact, C does not have a data type that holds strings. Strings are stored as arrays of chars that are terminated by a NUL character.

The value of the expression 'K' is equal to the character code assigned to the letter K in the execution character set. This is usually ASCII.

EDIT: Fix typos.
 
Last edited:

Thread Starter

King2

Joined Jul 17, 2022
163

WBahn

Joined Mar 31, 2012
29,979
The size of char data type is 1 byte, which means that the compiler can store a maximum of 255 characters.

unsigned defined between 0 to 255
signed defined between -127, 0, 128

This table does not show the character list for range -127 to 0 https://www.rapidtables.com/code/text/ascii-table.html

What characters are stored in the range of 0 to -127?
As I said, a char must be a minimum of 8 bits. It can be more. It must be able to store all nonnegative integers less than 128. See Section 5.2.4.2.1 of the C99 standard.

The compiler implementer only has to meet those requirements (though there are some consistency requirements based on other decisions they make).

So one compiler might have char be a signed integer that can store values between -128 and +127 inclusive, while another compiler might have it be an unsigned integer that can store values between 0 and +255, inclusive. Yet another might make a char a two-byte unsigned value.

ASCII is a 7-bit character set, so all that is required is that the values 0 to +127 be supported. Anything else is allowed, but not required.

The C language standard does not require that the execution character set be ASCII. The standard requires the execution character set to contain the 26 upper and 26 lower case English letters, the 10 decimal digits, a specific set of 29 graphic characters, the space character, horizontal tab, vertical tab, the form feed, and the null character. It must also have control characters for alert, backspace, carriage return, and new line. So it only requires a core set of 100 codings. The other 28 are locale-specific. The decimal digits must have codes that are sequential and increasing. The letters to NOT have to be ordered, which is something that nearly everyone that writes C programs is unaware of and write code that relies on this behavior.
 

xox

Joined Sep 8, 2017
838
The size of char data type is 1 byte, which means that the compiler can store a maximum of 255 characters.

You seem to be confusing the "range of values" that can be stored in a (unsigned) char with a "fixed array of characters" there.

Anyway the C standard does not dictate the size of 'char' although it must be (and usually is) at least 8 bits.

What characters are stored in the range of 0 to -127?

The plain 'char' type is neither guaranteed to be signed nor unsigned. That decision is strictly up to the implementation (your compiler). So if you most definitely want a 'signed char' then declare it as such. There probably aren't very many use cases for it but you could say encode an 8-bit audio signal or some such.

At any rate the size of the variable is determined at the compile step. Usually the compiler produces machine code which can then run on your own machine. But if you are using GCC for example you can also instruct it to target (ie. generate code for) another system.
 
Top