views:

675

answers:

5

Hi, The questions shown below is an interview question

Q)You are given have a datatype, say X in C.

The requirement is to get the size of the datatype, without declaring a variable or a pointer variable of that type,

And, of course without using sizeof operator !

I am not sure if this question was asked before in SO.

Thanks and regards Maddy

+2  A: 

Declare a structure with a member of that type, then use offsetof to compute the size?

struct outer
{
     X x;
     char after;
};

offsetof(outer, after) should give you the (aligned) size of x. Note that I'm not declaring a variable of that type per se, nor a pointer to the type, but I'm including it as a member of a structure declaration, where I measure the location of the member that comes after it.

The offsetof macro can be defined as

#define offsetof(S, f) ((size_t)(&((S *)0)->f))
John Källén
"without declaring a variable or a pointer variable of that type" ?
tur1ng
@John Källén-Can you please give me a better explanation for that?I am not clear with the answer.
maddy
I argue that here X is not used a variable, because memory for X is not allocated.
modosansreves
The offsetof macro computes the offset of a member within a structure. If I compute the offset of 'after' in the structure 'outer', I get the number of bytes that are "before" it in that structure. This should be the same as the size of X, with some possible bytes added for alignment. Actually, changing the int to a char would alleviate the alignment constraint.
John Källén
@John Källén...Thanks a lot.Infact i was not sure about the offsetof macro used.
maddy
+1 for only answer that meets the requirements and doesn't invoke undefined behavior.
R..
I'm a bit worried about if the offset of `after` is required to be the size of `x`, though. How about: `struct outer { X x[2]; };` and then use `offsetof(struct outer, x[1])`?
R..
+18  A: 

Hi,

#define sizeof_type( type )  (size_t)((type*)1000 + 1 )-(size_t)((type*)1000)

The original is from this discussion. http://www.linuxquestions.org/questions/programming-9/how-to-know-the-size-of-the-variable-without-using-sizeof-469920/

Teddy
easy enough - although the 1000 is confusing; can't we just use 0?
Elemental
Yes, you can use 0 also.
Teddy
Undefined behavior.
R..
+17  A: 

This should do the trick:

#include <stdio.h>

typedef struct
{
   int i;
   short j;
   char c[5];

} X;

int main(void)
{
   size_t size = (size_t)(((X*)0) + 1);
   printf("%lu", (unsigned long)size);

   return 0;
}

Explanation of size_t size = (size_t)(((X*)0) + 1);

  • assuming a sizeof(X) would return 12 (0x0c) because of alignment
  • ((X*)0) makes a pointer of type X pointing to memory location 0 (0x00000000)
  • + 1 increments the pointer by the the size of one element of type X, so pointing to 0x0000000c
  • the expression (size_t)() casts the address, that is given by the expression (((X*)0) + 1) back to an integral type (size_t)

Hope that gives some insight.

Frank Bollack
Actually, the main point in this site is to explain how things work: The way people learn is not by having an answer told to them, it's by having it EXPLAINED.
Ed Woodcock
@Frank Bollack...What does this line mean in the program of yours?size_t size = (size_t)(((X*)0) + 1); in the main function.
maddy
@Ed: Thanks for bringing me back to earth.
Frank Bollack
@maddy: see my edited answer
Frank Bollack
@Frank..Thanks a lot for that.
maddy
Pointer arithmetic on invalid pointers yields undefined behaviour (as does 'void main' and using the wrong printf conversion specifier).
fizzer
@Frank No problem, -1 retracted :) I'd upvote now but the slightly bizarre voting rules don't let me.
Ed Woodcock
Beside the undefined behaviour, a NULL pointer is not guaranteed to have all bits 0. An implementation is even allowed to have different NULL pointer representations for different types.
Secure
@fizzer: fixed most issues, but can you give a reference for your first statement.
Frank Bollack
fizzer
@fizzure: Pointer arithmetic is valid for an invalid pointer (pointer with an *invalid* value). When adding or subtracting from a pointer, there is no check of validity. Validity is checked when the pointer is dereferenced.
Thomas Matthews
@Thomas: No, even reading the value of an invalid pointer is already undefined behaviour. See page 49 in the link fizzer gave: "Regardless how an invalid pointer is created, any use of it yields undefined behavior." And from the Standard, Annex J.2: "The behavior is undefined in the following circumstances: [...]The value of a pointer to an object whose lifetime has ended is used (6.2.4)." *Used*, not dereferenced.
Secure
The rationale even specifies exactly one situation where pointer arithmetic on an invalid pointer might cause a crash: On a segmented architecture, the runtime can look at the segment descriptor table to figure out what the resulting pointer of the addition should be. For invalid pointers, that won't exist, and crash.Here's a little more commentary on the same lines: http://james-iry.blogspot.com/2010/04/good-math-bad-pointer-math.html
Greg Rogers
+2  A: 

This is not exactly the answer to your question, but I want to share some thought.

Teddy's answers is absolutely right.

I don't understand why interviewers ask such questions. See even if I answer this question, whats the point, where do u use such techniques in reality?

I have seen interviewers (ppl who took my interviews and my co-workers taking interviews) asking such useless questions. Instead of these questions, if they ask something that is relevant, Probably like, if you are a system programmer, if they ask you abt OS concepts or Deadlock scenarios or Some algorithms, don't you think the point of taking interview served?

What do you guys think?

Microkernel
@Microkernel--Yah tats perfectly true.But u dont go and question them abt the way they take these questions which are really irrelevant to the job you are applying.
maddy
@Microkernel - yes, I totally agree. I also experienced the same situation. Even some the interviewers don't know the answer and they just took it from the internet.
Teddy
@Microkernel - Its just testing how you solve problems by using a silly but unexpected scenario that you have likely not encountered. I have interviewed an alarming number of programmers that can't adequately solve simple programming problems.
Tim Post
+2  A: 

Hi,

You can typecast 0 (or any arbitrary value) to type datatype X* to find the size of the datatype, just like the below example:

    #include <stdio.h>

    struct node{
        char c;
        int i;
    };

    int main()
    {
        printf("Sizeof node is: %d\n", ((char *)((struct node *)0 + 1) - (char *)((struct node *)0)));   
// substract 2 consecutive locations starting from 0 that point to type node, 
//typecast these values to char * to give the value in number of bytes.
        return 0;
    }
juventus
Undefined behavior.
R..