dotslash
dotslash

Reputation: 2061

Explain variable declaration in C

I found this declaration in a C program

 char huge * far *p;

Explanation: p is huge pointer, *p is far pointer and **p is char type data variable.

Please explain declaration in more detail.

PS: I'm not asking about huge or far pointer here. I'm a newbie to programming

Upvotes: 1

Views: 611

Answers (4)

Medinoc
Medinoc

Reputation: 6608

Back in the 16-bit days on 8086, it would have declared a 32-bit pointer to a "normalized" 32-bit pointer to char (or to the first of an array thereof).

The difference exists because 32-bit pointers were composed of a segment number and offset between that segment, and segments overlapped (which meant two different pointers could point to the same physical address; example: 0x1200:1000 and 0x1300:0000). The huge qualifier forced a normalization using the highest segment number (and therefore, the lowest possible offset).

However, this normalization had a cost performance-wise, because after each operation that modified a pointer, the compiler had to automatically insert a code like this:

ptr = normalize(ptr);

with:

void huge * normalize(void huge *input)
{
    unsigned long input2 = (unsigned long)input;
    unsigned short segment = input >> 16;
    unsigned short offset = (unsigned short)input;

    segment += (offset >> 4);
    offset &= 0x000F;

    return ((unsigned long)segment) << 16 | offset;
}

The upside was the advantage of using your memory like it was flat, without worrying about segments and offsets.

Upvotes: 1

nurettin
nurettin

Reputation: 11736

Huge and far pointers are not part of standard C. They are borland extensions to the C language for managing segmented memory in DOS and Windows 16/32bit. Functionally, what the declaration says is **p is a char. That means "dereference p to get a pointer to char, dereference that to get a char"

In order to understand C pointer declarator semantics try this expression instead:

int* p; 

It means p is a pointer to int. (hint: read from right to left)

int* const p;

This means p is a const pointer to int. (so you can't change the value of p) Here's a proof of that:

p= 42; // error: assignment of read-only variable ‘p’

Another example:

int* const* lol; 

This means lol is a pointer to const pointer to int. So the pointer which lol points at cannot point at another int.

lol= &p; // and yes, p cannot be reassigned, so we are correct.

In most cases reading from right to left makes sense. Now read the expression in question from right to left:

char huge * far *p;

Now the huge and far are just behaviour specifiers for pointers created by borland. What it actually means is

char** p;

"p is a pointer to pointer to char"

That means whatever p points to, points to a char.

Upvotes: 2

Lundin
Lundin

Reputation: 213458

Clarification to the other answers:

The far keyword is non-standard C, but it is not just an old obsolete extension from ancient PC days. Today, there are many modern 8 and 16 bit CPUs that uses "banked" memory to extend the amount of addressable memory beyond 65k. Typically they use a special register to pick a memory bank, effectively ending up with 24-bit addresses. All small microcontrollers on the market with RAM+flash memory > 64kb use such features.

Upvotes: 0

Dayal rai
Dayal rai

Reputation: 6606

**p is character.Now a pointer pointing to address of this character will have value &(**p). Again if you want to take pointer to this pointer then next will be &(*p) and result will be p only.

If you read below sentence from right to left, you will get it all

p is huge pointer, *p is far pointer and **p is char type data variable.

In a nutshell virtual addresses on an Intel x86 chip have two components - a selector and an offset. The selector is an index into a table of base addresses [2] and the offset is added onto that base address. This was designed to let the processor access 20 bit (on a 8086/8, 186), 30 bit (286) or 46 bit (386 and later) virtual address spaces without needing registers that big.

'far' pointers have an explicit selector. However when you do pointer arithmetic on them the selector isn't modified.

'huge' pointers have an explicit selector. When you do pointer arithmetic on them though the selector can change.

Upvotes: 2

Related Questions