www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/11/06/07:20:28

From: Alex Vinokur <alexvn AT bigfoot DOT com>
Newsgroups: alt.comp.lang.learn.c-c++,comp.lang.c++,comp.os.msdos.djgpp
Subject: Holes in structure
Date: Tue, 06 Nov 2001 14:07:29 +0200
Organization: Scopus Network Technologies
Lines: 353
Message-ID: <3BE7D280.C1732E58@bigfoot.com>
NNTP-Posting-Host: gateway.scopus.co.il (194.90.203.161)
Mime-Version: 1.0
X-Trace: fu-berlin.de 1005048639 35250082 194.90.203.161 (16 [79865])
X-Mailer: Mozilla 4.7 [en] (Win98; I)
X-Accept-Language: en
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

===============================================================
Windows98
gpp : GNU C++ version 2.95.3 20010315/djgpp (release) (djgpp)
      compiled by GNU C version 2.95.3 20010315/djgpp (release).
===============================================================


Hi,

Here is some program that detects holes in structure.
Its output is not perfectly clear to me.
The questions are below (after run-log file).


#########################################################
################### C++ code : BEGIN ####################
// File main.c

#include <string>
#include <iostream>
#include <typeinfo>
#include <iomanip.h>

//===========================================
//================= DEFINES =================
//===========================================
#define ITEM_INTERNAL_ADDRESS(s, item) &(((s*)0)->item)
#define ITEM_ITSELF(s, item)  ((s*)0)->item

#define SHOW_ITEM_INFO(s, item)    \
 show_item_info (    \
  #s,     \
  #item,     \
  gstr_builtin_typename(ITEM_ITSELF(s, item)), \
  (size_t)ITEM_INTERNAL_ADDRESS(s, item), \
  sizeof (ITEM_ITSELF(s, item))  \
  )

#define SHOW_STRUCT_INFO(x)  \
 show_struct_info (  \
  #x,   \
  sizeof(x)  \
  )


//===========================================
//============= STATIC VARIABLES ============
//===========================================
static size_t prev_item_size_s = 0;
static size_t prev_item_address_s = 0;
static size_t size_of_all_items_s = 0;
static size_t sum_of_all_holes_s = 0;


//===========================================
//=========== AUXILIARY FUNCTIONS ===========
//===========================================
//--------------------------------
void show_item_info (
 const string& struct_name_i,
 const string& item_name_i,
 const string& item_type_name_i,
 const size_t item_address_i,
 const size_t item_sizeof_i
 )
//--------------------------------
{
size_t hole_value = 0;

  hole_value = item_address_i - (prev_item_address_s +
prev_item_size_s);

  cout.setf (ios::left, ios::adjustfield);
  cout << struct_name_i
   << "."
   << setw(6)
 << item_name_i.c_str()
 << setw(10)
 << string (" (" + item_type_name_i + ")").c_str()
 << "-> Address = "
 << setw(3)
 << item_address_i
 << " : sizeof = "
 << item_sizeof_i
 << " : ";

  if (hole_value)
  {
    cout << "Hole = " << hole_value << " (before item)" ;
  }
  else
  {
    cout << "No hole";
  }
  cout << endl;

  //-------------------------------
  prev_item_size_s    = item_sizeof_i;
  prev_item_address_s = item_address_i;

  size_of_all_items_s += item_sizeof_i;
  sum_of_all_holes_s  += hole_value;

} // show_item_info


//--------------------------------
void show_struct_info (
 const string& struct_type_name_i,
 const size_t struct_sizeof_i
 )
//--------------------------------
{
  cout  << "Struct "
 << struct_type_name_i
 << " : "
 << endl
 << "\t"
 << "sizeof\t\t = "
 << struct_sizeof_i
 << endl
 << "\t"
 << "All items sum\t = "
 << size_of_all_items_s
 << endl
 << "\t"
 << "Diff ("
 << struct_sizeof_i
 << " - "
 << size_of_all_items_s
 << ")\t = "
 << (struct_sizeof_i - size_of_all_items_s)
 << endl
 << "\t"
 << "All holes sum\t = "
 << sum_of_all_holes_s
 << endl;

} // show_struct_info


//--------------------------------
void init_counters ()
//--------------------------------
{
  prev_item_size_s    = 0;
  prev_item_address_s = 0;
  size_of_all_items_s = 0;
  sum_of_all_holes_s  = 0;
} // init_counters


//--------------------------------
#define IF_TYPE(x) if (typeid(T) == typeid(x)) return #x
template <typename T>
string gstr_builtin_typename(const T&)
//--------------------------------
{
  IF_TYPE(char);
  IF_TYPE(short);
  IF_TYPE(int);
  IF_TYPE(long);
  IF_TYPE(float);
  IF_TYPE(double);
  return "Undefined typename";
}  // gstr_builtin_typenameconst


//===========================================
//============= TESTED STRUCTURES ===========
//===========================================
//-----------
struct type0
{
};
//-----------
struct type1
{
  long   item1;
  char   item2;
  short  item3;
  char   item4;
  long   item5;
  long   item6;
  int    item7;
  short  item8;
  short  item9;
  char   item10;
  char   item11;
  long   item12;
  float  item13;
  double item14;
  char   item15;
};


//===========================================
//============== MAIN FUNCTION ==============
//===========================================
int main ()
{

  //------ struct type1 ------

  init_counters ();

  SHOW_ITEM_INFO (type1, item1);
  SHOW_ITEM_INFO (type1, item2);
  SHOW_ITEM_INFO (type1, item3);
  SHOW_ITEM_INFO (type1, item4);
  SHOW_ITEM_INFO (type1, item5);
  SHOW_ITEM_INFO (type1, item6);
  SHOW_ITEM_INFO (type1, item7);
  SHOW_ITEM_INFO (type1, item8);
  SHOW_ITEM_INFO (type1, item9);
  SHOW_ITEM_INFO (type1, item10);
  SHOW_ITEM_INFO (type1, item11);
  SHOW_ITEM_INFO (type1, item12);
  SHOW_ITEM_INFO (type1, item13);
  SHOW_ITEM_INFO (type1, item14);
  SHOW_ITEM_INFO (type1, item15);

  cout << endl;
  SHOW_STRUCT_INFO (type1);

  //------ struct type0 ------

  init_counters ();

  cout << endl;
  cout << endl;
  SHOW_STRUCT_INFO (type0);

  return 0;
}


#################### C++ code : END #####################


#########################################################
################### Compiling : BEGIN ###################

%gpp -v main.c

Reading specs from d:/sys/djgpp/lib/gcc-lib/djgpp/2.953/specs
gcc version 2.95.3 20010315/djgpp (release)
 d:/sys/djgpp/lib/gcc-lib/djgpp/2.953/cpp0.exe -lang-c++ -v -D__GNUC__=2
-D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -Dunix -Di386 -DGO32
-DDJGPP=2 -DMSDOS -D__unix__ -D__i386__ -D__GO32__ -D__DJGPP__=2
-D__MSDOS__ -D__unix -D__i386 -D__GO32 -D__DJGPP=2 -D__MSDOS
-Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)
-D__EXCEPTIONS -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__
-D__tune_pentium__ -imacros d:/sys/djgpp/lib/djgpp.ver -remap main.c
D:\SPE\BACKUP\ccXMYhM9.ii
GNU CPP version 2.95.3 20010315/djgpp (release) (80386, BSD syntax)
#include "..." search starts here:
#include <...> search starts here:
 d:/sys/djgpp/lang/cxx
 d:/sys/djgpp/lib/gcc-lib/djgpp/2.953/include
 d:/sys/djgpp/include
End of search list.
The following default directories have been omitted from the search
path:
 $DJDIR/lib/gcc-lib/djgpp/2.953/../../../../djgpp/include
End of omitted list.
 d:/sys/djgpp/lib/gcc-lib/djgpp/2.953/cc1plus.exe
D:\SPE\BACKUP\ccXMYhM9.ii -quiet -dumpbase main.cc -version -o
D:\SPE\BACKUP\ccLAGHuy.s
GNU C++ version 2.95.3 20010315/djgpp (release) (djgpp) compiled by GNU
C version 2.95.3 20010315/djgpp (release).
 d:/sys/djgpp/bin/as.exe -o D:\SPE\BACKUP\ccyOjq3k.o
D:\SPE\BACKUP\ccLAGHuy.s
 d:/sys/djgpp/lib/gcc-lib/djgpp/2.953/collect2.exe
d:/sys/djgpp/lib/crt0.o -Ld:/sys/djgpp/lib/gcc-lib/djgpp/2.953
-Ld:/sys/djgpp/bin -Ld:/sys/djgpp/lib D:\SPE\BACKUP\ccyOjq3k.o -lstdcxx
-lm -lgcc -lc -lgcc -Tdjgpp.djl
 d:/sys/djgpp/bin/stubify.exe -v a.out
stubify for djgpp V2.X executables, Copyright (C) 1995 DJ Delorie
stubify: a.out -> a.000 -> a.exe


#################### Compiling : END ####################


#########################################################
############### Running (log file) : BEGIN ##############

%a.exe

type1.item1  (long)   -> Address = 0   : sizeof = 4 : No hole
type1.item2  (char)   -> Address = 4   : sizeof = 1 : No hole
type1.item3  (short)  -> Address = 6   : sizeof = 2 : Hole = 1 (before
item)
type1.item4  (char)   -> Address = 8   : sizeof = 1 : No hole
type1.item5  (long)   -> Address = 12  : sizeof = 4 : Hole = 3 (before
item)
type1.item6  (long)   -> Address = 16  : sizeof = 4 : No hole
type1.item7  (int)    -> Address = 20  : sizeof = 4 : No hole
type1.item8  (short)  -> Address = 24  : sizeof = 2 : No hole
type1.item9  (short)  -> Address = 26  : sizeof = 2 : No hole
type1.item10 (char)   -> Address = 28  : sizeof = 1 : No hole
type1.item11 (char)   -> Address = 29  : sizeof = 1 : No hole
type1.item12 (long)   -> Address = 32  : sizeof = 4 : Hole = 2 (before
item)
type1.item13 (float)  -> Address = 36  : sizeof = 4 : No hole
type1.item14 (double) -> Address = 40  : sizeof = 8 : No hole
type1.item15 (char)   -> Address = 48  : sizeof = 1 : No hole

Struct type1 :
 sizeof   = 52
 All items sum  = 43
 Diff (52 - 43)  = 9
 All holes sum  = 6


Struct type0 :
 sizeof   = 1
 All items sum  = 0
 Diff (1 - 0)  = 1
 All holes sum  = 0


################ Running (log file) : END ###############


Questions.
 1. struct type0 (empty) :
           Why is 'sizeof' = 1?

 2. struct type1 :
           Why is not 'Diff' (between 'sizeof' and 'All items sum')
  equal 'All holes sum' ?
     Note. 'Diff' = 9, 'All holes sum' = 6.
    Where has 3 bytes ('Diff' - 'All holes sum') gone?

 3. struct type0 and type1 :
           Why is not ('Diff' - 'All holes sum') the same value for
type0 and type1.
           Note. type0  : 'Diff' - 'All holes sum' = 1 - 0 = 1
                 type1  : 'Diff' - 'All holes sum' = 9 - 6 = 3


  Thanks,
  ===========================
  Alex Vinokur
    mailto:alexvn AT bigfoot DOT com
    mailto:alexvn AT dr DOT com
    http://up.to/alexvn
    http://go.to/alexv_math
  ===========================


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019