Topic: HELP with sizeof(), URGENT


Author: gtj@goanna.cs.rmit.oz.au (Glenn T Jayaputera)
Date: 11 Mar 93 13:10:59 GMT
Raw View
The problem that I am having is this:
I have (assume) 2 files, main.cpp and file1.cpp.
In file1.cpp I have declaration
  int table[] = {1,2,3,4,5,6};

Since this `table' is needed everywhere I declare the following in file1.h
  extern int table[];

In main.cpp I would like to know the no. of elements in `table', so I use:
  nitem = sizeof(table) / sizeof(int);
                 ^^^^^
However, this is where it fails.  The compiler (BC++) complaints that
this type is not allowed. However after looking at C++ bible (Stroustrup's),
it says that sizeof() cannot be used with unspecified dimension array.
Hence if I change my declaration in file1.h into the following, it works
  extern int table[6];

However, if I know the no. of item is 6, then why do I need to:
  sizeof() / sizeof()

I am wondering if somebody has a way to tweak this problem since I have
alot of arrays like `table', and would like to keep it generic (dont want to
explicitly define the no of element of an array).

Many thanks in advance
Glenn Jayaputera




Author: miketoms@calladin.demon.co.uk (Mike Toms)
Date: Fri, 12 Mar 1993 17:08:33 +0000
Raw View
In article <16980@goanna.cs.rmit.oz.au> gtj@goanna.cs.rmit.oz.au writes:

>The problem that I am having is this:
>I have (assume) 2 files, main.cpp and file1.cpp.
>In file1.cpp I have declaration
>  int table[] = {1,2,3,4,5,6};

>Since this `table' is needed everywhere I declare the following in file1.h
>  extern int table[];
>
>In main.cpp I would like to know the no. of elements in `table', so I use:
>  nitem = sizeof(table) / sizeof(int);
>                 ^^^^^
>However, this is where it fails.  The compiler (BC++) complaints that
>this type is not allowed. However after looking at C++ bible (Stroustrup's),
>it says that sizeof() cannot be used with unspecified dimension array.
>Hence if I change my declaration in file1.h into the following, it works
>  extern int table[6];
>
>However, if I know the no. of item is 6, then why do I need to:
>  sizeof() / sizeof()
>
>I am wondering if somebody has a way to tweak this problem since I have
>alot of arrays like `table', and would like to keep it generic (dont want to
>explicitly define the no of element of an array).
>
>Many thanks in advance
>Glenn Jayaputera
>
--
Hi Glenn,
The problem is that during the compilation of the file with the extern,
all that file has to work with is a pointer to an array of chars that will
be fixed up at link-time. The sizeof() function is, I believe, normally
replaced at compile time. A statement including sizeof an unspecified no of
element array, should be done in thew same compilation unit.

Try the following:
------------------
<main.cpp>
------------------
void print(); // prototype
int table[] = {1,2,3,4,5,6};
int size = sizeof(table) / sizeof(int);
void main(void)
{
    print();
}
----------------
<file1.cpp>
----------------
#include <iostream.h>
extern int* table;
extern int size;
void print()
{
cout << "The number of items is "
  << size
  << endl;
}
-----------------
Setting the size in the same module and making it extern in other
modules should achieve what you desire

Hope this is a suitable solution - Mike Toms
--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\   Mike Toms  - Calladin Computing Ltd - Swansea, Wales             /
/   Editor of Overload - Turbo C++ Special Interest Group magazine   \
\   of the C User Group (UK)                                         /
/   Please email me at miketoms@calladin                             \
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/




Author: dwr@cci632.cci.com (Donald W. Rouse II)
Date: Wed, 17 Mar 1993 18:25:17 GMT
Raw View
In article <731956113snz@calladin.demon.co.uk> miketoms@calladin.demon.co.uk writes:
>Try the following:
>------------------
><main.cpp>
>------------------
>void print(); // prototype
>int table[] = {1,2,3,4,5,6};
>int size = sizeof(table) / sizeof(int);
>void main(void)
>{
>    print();
>}
>----------------
><file1.cpp>
>----------------
>#include <iostream.h>
>extern int* table;
        ^^^^^^^^^^
>extern int size;
>void print()
>{
>cout << "The number of items is "
>  << size
>  << endl;
>}
>-----------------

That won't work, either.  Instead of "extern int* table"
you must use "extern int table[]".  This is because table
is not a pointer to int, but an array of int.  While it's
true that you can _use_ an array name as a pointer, you
must _declare_ (and define) it as an array.

On a slightly different topic, I think a better solution
to the original problem is to put the definitions in a
source file, and the declarations in an include file.





Author: miketoms@calladin.demon.co.uk (Mike Toms)
Date: Fri, 19 Mar 1993 01:34:31 +0000
Raw View
In article <1993Mar17.182517.23695@cci632.cci.com> dwr@cci632.cci.com writes:

>That won't work, either.  Instead of "extern int* table"
>you must use "extern int table[]".  This is because table
>is not a pointer to int, but an array of int.  While it's
>true that you can _use_ an array name as a pointer, you
>must _declare_ (and define) it as an array.

You are right, next time and I will use a floppy disk to
transfer between the machine with the compiler and the one
with the modem, and not just try and remember what I did!!!!

>
>On a slightly different topic, I think a better solution
>to the original problem is to put the definitions in a
>source file, and the declarations in an include file.
>

I disagree, the original problem requires the size of the
table to be determined without the programmer counting the elements
in the table.

My approach to solving this problem in the past has been to incorporate
both definition and declaration in an include file and use conditional
compilation to determine which is used. My approach in the original reply
was to modify as little as possible, in order not to confuse the situation.
(Which I managed to do anyway).

My prefered solution would have been:

-----sizeof.h-----
#define LOCAL
#ifdef DEFINE
#define SCOPE LOCAL
#else
#define SCOPE extern
#endif

// if '#define DEFINE' is setup before the #include
// the local (i.e. blank scope is set up and the definition
// is used, otherwise the extern scope is used and a declaration
// is used

SCOPE int table[]
#ifdef DEFINE
 = {1,2,3,4,5,6}
#endif
;

SCOPE int size
#ifdef DEFINE
 = sizeof(table)/sizeof(int)
#endif
;

#ifdef DEFINE
#undef DEFINE
#endif

-----main.cpp-----
#define DEFINE
#include "sizeof.h"
void print();
void main(void)
{
 print();
}

-----sizeof.cpp---
#include <iostream.h>
#include "sizeof.h"
void print()
{
cout << "The number of items is "
     << size
     << endl;
cout << "Last item is "
     << table[size-1]
     << endl;
}

--------------------

This has the effect of ensuring that the definition and any declarations
are the same. Obvious to say that only one compilation unit out of all
the ones making up the executible should have the '#define DEFINE'
pre-compiler statement.

Do you think this approach has any merit? Please let me know.

Many thanks Mike.

***Humble pie dutifully eaten for the int* thingy.***
--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\   Mike Toms  - Calladin Computing Ltd - Swansea, Wales       /
/   Editor of Overload - TC++ Special Interest Group magazine  \
\   of the C User Group (UK)                                   /
/   Please email me at miketoms@calladin                       \
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/