home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!elroy.jpl.nasa.gov!usc!wupost!uwm.edu!ogicse!mintaka.lcs.mit.edu!ai-lab!life.ai.mit.edu!tmb
- From: tmb@arolla.idiap.ch (Thomas M. Breuel)
- Newsgroups: comp.lang.c++
- Subject: Re: zero-length datatype
- Message-ID: <TMB.92Sep8141523@arolla.idiap.ch>
- Date: 8 Sep 92 18:15:23 GMT
- Article-I.D.: arolla.TMB.92Sep8141523
- References: <TMB.92Sep7171355@arolla.idiap.ch> <MCGRANT.92Sep7142456@rascals.stanford.edu>
- Sender: news@ai.mit.edu
- Reply-To: tmb@idiap.ch
- Distribution: comp
- Organization: IDIAP (Institut Dalle Molle d'Intelligence Artificielle
- Perceptive)
- Lines: 152
- In-reply-to: mcgrant@rascals.stanford.edu's message of 7 Sep 92 21:24:56 GMT
-
- In article <MCGRANT.92Sep7142456@rascals.stanford.edu> mcgrant@rascals.stanford.edu (Michael C. Grant) writes:
-
- In article <TMB.92Sep7171355@arolla.idiap.ch>
- tmb@arolla.idiap.ch (Thomas M. Breuel) writes:
-
- Consider, for example, the following template class definition:
-
- template <class A,class B>
- struct Bar {
- A x;
- B y;
- };
-
-
- Now, the straightforward declaration obviously fails.
-
- Bar<int,void> s;
-
- I don't find this straightforward at all. It seems to me that a
- parametrized type is not properly parametrized if some of the types
- may contain a 'void' entry like that.
-
- "void" (or its equivalent) is a perfectly good type in many
- programming languages. It has exactly one value and does not need to
- be represented in the data structure at all precisely because it has
- only one value.
-
- Perhaps there should be two
- different parametrized types, one that contains B and one that
- doesn't, and sufficient conversion operators, if necessary, between
- the two of them.
-
- I thought C++ was about code reuse and not imposing arbitrary
- restrictions.
-
- It is quite common that dictionary classes are used only for their key
- values, not for their corresponding data values. For the simplest
- example, consider "awk" arrays, where you don't even have a choice.
- There is nothing "unclean" or "strange" about this: you are simply not
- interested in associating a non-trivial value with your keys. It would
- be nice if the data values that you are not using didn't occupy any
- memory.
-
- It is also quite necessary. Suppose that 'void' had zero length,
- and you instantiated
-
- Bar<void,int>s.
-
- Then the pointer to member A would have the same address as the pointer
- to member B! That should certainly not happen, since they are two different
- objects. The ARM has something quite specific to say about that.
-
- I don't see why that is a problem. In particular, existing programs
- don't use the feature, and whether I use it in new programs would be
- up to me.
-
- One fix might be to allow definitions of objects of type "void", give
- them zero length, and introduce a single value for objects of type
- "void", denoted "void()". Of course, there would be some minor
- conflicts with the "function(void)" syntax, but those could be
- resolved compatibly. Alternatively, another built-in special type
- could be introduced, say, called "unit", that would be available
- (only) after "#include <unit.h>".
-
- I certainly should not have to 'include' any definition of a built-in
- type.
-
- You already have to "#include" lots of things in order to get at
- compiler primitives (including some built-in types in some compilers).
- For example, some of the definitions in "math.h", "alloca.h" and
- "setjmp/longjmp" are often compiler built-ins.
-
- The reason for making such language extensions dependent on a
- "#include" is to reduce the potential for name conflicts with existing
- code. Commonly, such "#include" files contain something like the
- following:
-
- /* __builtin_alloca is recognized as a keyword by the compiler */
- #define alloca(x) __builtin_alloca(x)
-
- I don't understand why those 4 bytes are causing you such a stink. Perhaps
- you could enlighten us as to why a truly zero length data type is even
- necessary?
-
- Under the current rules,
-
- struct nothing {};
- HashTable<int,nothing> table(1000000);
-
- table takes up 8Mbytes (on most machines). If you could write
-
- HashTable<int,void> table(1000000);
-
- table takes up 4Mbytes.
-
- Also, I would like to see what templated member functions that
- operate on the above object would have to do to deal with the case of
- a 'void' type.
-
- Consider:
-
- template <class Key,class Value>
- class HashTable {
- public:
- void add(Key key,Value value);
- int is_member(Key key);
- Value lookup(Key key);
- };
-
- If you instantiate this using "HashTable<int,void>", you would get
- the equivalent of:
-
- class HashTable_int_void {
- public:
- void add(int &key,void &value);
- int key_is_member(int &key);
- void lookup(int &key);
- };
-
- Now, this is a perfectly useful data type. Consider:
-
- Bag<int> intersect_integers(Bag<int> &a,Bag<int> &b) {
- HashTable<int,void> table;
- Bag<int> result;
- for(int i=0;i<a.length();i++)
- table.add(a(i),void());
- for(i=0;i<b.length();i++)
- if(key_is_member(table.b(i)))
- result.add(b(i));
- return result;
- }
-
- Obviously, there is little reason to call the function "lookup" now,
- but everything would still be consistent. Consider, for example,
- the following code fragment:
-
- Value x = lookup(some_key);
-
- This would simply turn into:
-
- void x = lookup(some_key);
-
- Obviously, a "void" variable could be initialized by the return value
- ("void()") of a "void" function.
-
- It's not a major thing, but I still find the current restriction
- pretty arbitrary (there are lots of sentences devoted in the ARM to
- saying "you can't do this with 'void' and you can't do that with
- 'void'"), and it is inconvenient. Other languages have the equivalent
- of the "void" value and "void" variables; why not C++?
-
- Thomas.
-