Random C things – part I

Hi There ! It’s been a while since I posted – I have just been busy with life  (read  “lazy” or occupied with random things). But, am back now.

This is not really a blog post per se. I just felt like putting up a refresher to people who are familiar with C programming. It’s in a concise question and answer format ; won’t take too long ! Go ahead … 🙂

01. Can two different type of variables be declared with same name ?

Example : int a ; and enum a { b = 2, c};

The answer to this is : Yes – if they are not in same scope (local / global scope) and variable name is not used for a “#define” constant. 

If both are in local or both are declared in global space – then there will be a clash in the symbol name space.

02. What happens to uninitialized const variable ?

It gets initialized to zero. Example : const int a; declaration will set “a” to zero and cannot be modified. Keyword “const” makes the variable a “read-only”.

Even when we use keyword “static” the variables are by default initialized to zero.

03. Can we have a structure with bit fields ? How to achieve this ?

Yes, we can!

For example :  If you want a structure that holds two variables whose values can range from 0 to 15 then , all we would need is two fields with 4 bits each. This can be achieved using a declaration as below :

struct sample{
uint8_t var1:4; // first variable 4 bits
uint8_t var2:4; // second variable 4 bits

04. What is structure packing?

We would want to make sure we are packing the structure variables “efficiently” – specially on embedded memory limited systems.

Example :
struct noPack{
char b; // one byte + one byte  implicit padding
uint16_t data; // two bytes
char c; // one byte + one byte implicit padding
a total of "6 bytes"

But, if we re-arrange this :
struct withPack{
uint16_t data; // 2 bytes
char b; // one byte
char c; // one byte
a total of "4 bytes" 

Yes, we saved 2 extra byte assignment just by rearranging and packing 
efficiently ! 
Usually the trick is to pack the structure starting with the biggest 
size data type (in this case (sizeof(uint16_t)) > sizeof(char)) 
to lowest size

05. What is integer overflow  ? How can we handle this ?

Yes, there can be problems when you cast a larger data type to smaller one -i.e., loss of information. Consider the example below :

uint16_t func1(uint8_t a ){
//do some operation and return
return (a+100);
Suppose, this function is used as below :
uint8_t temp = func1(10); // result returned is 16-bit
//but, implicitly gets truncated to 8-bit 
//(depending on the compiler's behavior)

Suppose input variable “a” was set to 0xFF  (max value for an 8-bit integer), adding a value of 100 requires more than 8 bits to hold the result of addition – resulting in an overflow when the value returned is stored in an 8 bit integer – “temp” in this example.

And, trust me when I say these can result in hard bugs to catch when they happen in production code. So, please take care of scenarios involving implicit conversions such as this ! Make sure you have fixed all the warnings your compiler spits out or at least take a look at the warning messages.

06. Why will I ever use a union?

Unions allow data members that are mutually exclusive to share memory. This is important specially in the embedded system cases where memory is a scarce resource.

For example : If you implementing protocol handler with different kinds of messages that can be exchanged, we could handle the different message types and their allocations as below on an embedded system :

// Declare a union with all types of different messages to be handled.
// All message types in the union shall share same memory.
// Only one of these messages would need to be handled by protocol implementation at 
// a given time -this means they are mutually exclusive and hence would be a good idea 
// to share the memory.

typedef union
  protocol_req_identity_type      identity;
  protocol_req_challenge_type     challenge;
  protocol_req_notification_type  notification;
} protocol_req_msg_union_type;

// Generic format to decipher a protocol message
// check mnessage type and cast to appropriate message type in structure.
typedef struct 
  protocol_msg_type_enum         msg_type; // can be a identity , challenge or a notification
  protocol_req_msg_union_type    msg_union;

07. Why do we need Enum ?

Well! One reason I can think of is – it’s not only important that we write efficient code but also readable code. Enum(s) provide us a way to add readability to our code.

Suppose you are writing some api and want to return custom status codes -1 , 1 and 2 – to mean different return status, to the caller. We can write human readable code as below, instead of using the status codes as numbers (-1, 1 ,2) directly.

//custom verbose return codes
typedef  enum codes{

// function / api that returns a status code 
cust_status func1(){
// Do some operation and return status codes to caller
// set error as default status
cust_status status = CUST_ERROR;

//you want the user to retry later
status = CUST_RETRY;
//do some processing 
//everything went fine
status = CUST_SUCCESS;
return status;

//caller checks the returned status code 
int main(){
if (CUST_SUCCESS == func1()){
else if(CUST_RETRY == func1()){
printf("Retry the operation later\n");

08. What is the difference between “#define” of a constant and declaring it “const int” ?

As a novice programmer, when I started with C , I wondered why were there two options to do the same thing – which one is to be used ?

#define TEST_VARIABLE 100      // pre-processor directive
int const TEST_VARIABLE = 100; // constant variable

#define is essentially a preprocessor directive. The C preprocessor shall replace all occurrences of the given variable in the code with the value before compiler compiles the code.

Whereas const is acted upon by compiler. It only indicates that the variable is “read only” , all rules of a variable apply to it as well. But, if a compiler doesn’t optimize and replace these occurrences, then there will be an overhead.

When you don’t really care about the types  -for example : a variable that holds a fixed constant could be #defined !   Also, if you are designing in a large team : #defines may be a good option as they throw a compile error when we redefine a local variable with same name, as in the example below.

//Global variable 
int const trials =10;

int func(){
// Someone decides to use same name for a local in the function but
// you intended to use global definition at a later point.
int trials= 20; 
// defining variable "trials" with a #define would have 
// thrown an error here.

// few 100 lines of code later

//suppose you intended to look up the global variable "trials"
int number_trials = trials; // this has 20, not the 10 that you wanted!!

09.  Can I assign a pointer to constant int to a pointer to an integer ?

You can ! But, don’t !!

Example :

const int * constptr; // pointer to constant integer

int* ptr; // pointer to an integer

const int var1 =10; // constant integer

constptr = &var1; // assign a const integer (const => read only)

ptr = (int*) constptr; //valid , but don’t !

*ptr = 15; // change value pointer – run time error !!

10. Compiler and volatile qualifier in C

Compilers with optimization enabled try to make code smaller and faster based on some rules.  Volatile keyword is used to indicate to compiler to “not optimize”.

There are cases where a variable may be updated in ways unknown to the compiler – such as :

  • Memory mapped input/output – peripheral registers,
  • Modification via signal interrupt – Global modified/accessed by other functions or ISR.
  • Shared global variable in multi-threaded programming

basically, where the updates made to the variable are not in the local scope of the code block. When this keyword is not used, the variables are cached to a CPU register or optimized out by the compiler.

“Volatile” ensures that the variable reads and writes are not optimized away.Consider the example for volatile usage below :

If you have a global variable (named value_to_write) that is shared between the main program that writes value from this variable to a port and an ISR that writes to this variable. We can have three cases that will have different behavior based on compiler optimization state and volatile qualifier is used or not.

  1. No compiler optimization : In this case , the main program code is not optimized and the ISR updated value gets written to the portX in main program
  2. With compiler optimization : In this case, the compiler looks at two different code blocks, each with variable named value_to_write as shown below. Since the compiler optimization is ON, compiler looks at main code block and unable to find updates/writes to the variable “value_to_write” , decides to optimize it out. Due to this optimization, only one value gets written to portX – 0, not the one updated by the ISR, which you wanted. This now calls for “volatile” usage.
  3. With compiler optimization enabled and volatile qualifier – now, if the variable value_to_write has a qualifier called “volatile” , although the compiler does not see a write to this variable in main code segment , it does NOT optimize it out. In this case portX will have the value updated by ISR, as expected.



But, there are some things to consider before using Volatile qualifier and they are listed here. Do check this link.

Yes, each of these topics deserve a separate blog. But, that’s all for now in this blog. Keep decoding !~



Static is a keyword  in C (also in C++/Java) used as storage or linkage class specifier in C. Storage indicates how the variable is to be stored in memory and linkage specifies the linkage scope to be applied during the linking process. There are various storage classes in C namely – auto, register , const and static. There are linkage specifiers such as extern or static. In this blog, we are going to understand the various facets of the keyword “static”. For a beginner or a new programmer, this can get confusing. But, not after we decode this today ! So, let’s begin.

Usage Scenarios in C

Static can mean different things based on different contexts of usage. There are three types of usage that I can think of in C:

a. Static to declare a global variable in C

Suppose you have written a .c file with following :

// File : test.c 

static int a; // global static variable

void func(){

int x;

printf(“Static variable value is %d \n”, a); // can access static variable 


In the example above declaring variable “a” static essentially restricts the usage of variable “a” to only inside the compilation unit / translation unit or the given “.c” file. No other file in your code can access this variable. So, in this scenario it is not really controlling the storage aspect but the scope of the variable. The scope is limited to the given file – meaning the functions inside this “.c” file alone can access or use the variable. Hence, static in this case essentially specifies “internal” linkage as opposed to using extern keyword usage – that specifies “External” linkage (note to self : we shall cover extern in the another blog).

b. Static to declare a variable inside a function in C

A variable declared “static” inside the scope of a function retains the value even after we exit the function – across multiple calls. By default variable inside function are treated as “auto” and are allocated on function stack ; but static is allocated in .DATA or .BSS section of memory.

To understand this scenario of usage consider the example below :

//Function with static variable

void func(){

static int counter; // static local variable in func().

counter++; // increment counter to count function calls

printf(“Call counter is %d” , counter);

} // counter’s state is preserved even after we hit this point. (auto variables are lost)

// Example multiple calls to function func() above :

void caller1(){

func(); // first call

}  //after this call , the function prints “Call counter is 1”

void caller2(){

func(); //second call

}//after this call , the function prints “Call counter is 2”

c. Static Function in C

The scope of these functions is limited to only the file they are contained in. We can think this as a way to attain “data encapsulation” in C as we see in OOP languages such as C++/Java.

Methods without static keyword are public while the ones with “static” keyword are “private” to the compilation unit / translation unit (the .c file).

Default Storage Specifier Rules

  1. Variables declared inside a function are considered “auto”
  2. Functions declared within a function are treated as “extern”
  3. Variables and functions declared outside a function are considered “static”, with external linkage

Static in c++

  1. In C++ it does not really specify a storage class. When a variable of a class is declared static (example variable named obj in the example below), it essentially means that all objects of that given class (exObj1  and exObj2 below) share same variable instance.
  2. If a function or member variable is declared static (example : variable named sample in the example code below), then it can be accessed without a  class object – using just the class name (check usage in cout “Example::sample”  below). This essentially means that the static member is associated only with class not the instance of the class or the “object”. It requires no instance of “this” operator.
  3. In case of inheritance, static “public” variables in the parent class are shared by the derived classes as well ; meaning a copy is not created. Whereas if they are declared “private” in parent class, then the derived classes cannot view or use the variable.


class Example{


static int sample;

Example(); //constructor

~Example(); //destructor



//constructor counts the objects created


static int obj; // static variable


cout<<“Object counter “<<obj<<endl;



#include “Example.h”

int main(){

Example exObj1 ; // when this is created constructor prints “Object counter 1”

Example exObj2; // when this is created constructor prints “Object counter 2”

cout<<“Accessing  public static variable without object : “<<Example::sample<<endl; // accessing static member without object


Initializing and defining static

By default all static variables that are not initialized are set to zero. They are initialized at compile time. Static variables contained within a “.c file” limits the usage of variable to within one compilation unit/translation unit. But, if they are declared in a header file and this header is included in multiple .c files, then there will be multiple copies of the same variable (one copy per .c file). This kind of defeats the purpose of declaring it as “static” to limit the usage scope to specific translation unit. So, if you really want to limit the scope, just put it in the .c file and use.

Static variables in Memory

If you have read this previous blog on “Memory and Program“, you would know where the static variables go to in the memory when you use them in your program. If the static variable is initialized it goes into the .DATA section where as uninitialized static variables go to the .BSS (Block Start Segment).

That’s all for today folks ! Isn’t low level coding fun !? ;). Until next time – keep decoding ~!

Tip #1 : Customize Sublime

Hey there ! It’s been a while since I posted something. I was trying to setup Sublime editor for my work at home. Thought I will share this tip that may be useful to you guys. Sublime comes with a single file compile option for C plus plus. This could be set as default build system using option : Tools->Build System-> C++ Single File. More info on Sublime Build Systems available here

However, I wanted to setup Sublime to compile multiple Cpp files in the given folder. So, all I did was to define a custom build option :

  • Tools-> Build System- > New Build System
  • Put the commands below into a new file:

“cmd”: [“g++”, “${file_path}/*.cpp”, “-o”, “$file_base_name”],
“working_dir”: “$folder”,
“selector”: “source.c++”,
“shell”: true,
“name”: “Run”,
“cmd”: [“g++”, “${file_path}/*.cpp”, “-o”, “$file_base_name”, “&&”, “$file_path/$file_base_name”],
“working_dir”: “$folder”,
“selector”: “source.c++”,
“shell”: true

  • Save the file as custom.sublime-build (can be custom or any name you want)
  • Set this as the default build system under
    • Tools->Build System->custom

Once you have your multiple cpp files in your workspace folder, use :

  • Ctrl+B to compile and
  • Ctrl+shift+B to run

Do you guys know how we could modify this to compile multi folder projects? Write to me at decodergirlblog@gmail.com.