Thread: which consumes more memory....

  1. #16
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    IMHO you're confusing default type sizes with the explicitly specified ones.
    I am afraid that I have never seen that syntax, and neither the C nor C++ standards mention it in the grammar or otherwise. The MinGW port of gcc 3.4.5 reports an error ("long, short, signed or unsigned invalid for 'obj'") with:
    Code:
    short enum var {x, y, z} obj;
    Changing the above to just:
    Code:
    short enum var {x, y, z};
    results in the warning "useless keyword or type name in empty declaration".

    Here is what section 6.7.2.2 of the 1999 edition of the C standard has to say about this:
    Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  2. #17
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    I am afraid that I have never seen that syntax, and neither the C nor C++ standards mention it in the grammar or otherwise. The MinGW port of gcc 3.4.5 reports an error ("long, short, signed or unsigned invalid for 'obj'") with:
    Code:
    short enum var {x, y, z} obj;
    Changing the above to just:
    Code:
    short enum var {x, y, z};
    results in the warning "useless keyword or type name in empty declaration".

    Here is what section 6.7.2.2 of the 1999 edition of the C standard has to say about this:
    Argh! forgot to add that declarations like long enum {x, y, x} obj; are vendor extensions and not part of the ANSI std.
    Nevertheless, the point was to demonstrate that the size of each obj variable is the same as its underlying enum type.

  3. #18
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    Nevertheless, the point was to demonstrate that the size of each obj variable is the same as its underlying enum type.
    Okay, though I do not see the connection between that and your assertion that I am "confusing default type sizes with the explicitly specified ones", since as you stated "explicitly specified ones" are actually vendor extensions. It is quite obvious that even though the C standard does not specify that the sizeof an enumeration must be the same as the sizeof its underlying type, such a relation is natural, and as mentioned the C++ standard specifies this explicitly.
    Last edited by laserlight; 06-27-2009 at 02:12 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #19
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by sanddune008 View Post
    Code:
    Following declaration
    #define IDLE_ST   0x01
    #define RX_ST      0x02 
    #define TX_ST      0x03
    #define NO_ST     0x04
    
                       or
     
    typedef enum {
                    IDLE_ST =0x01,
                    RX_ST ,  
                    TX_ST , 
                    NO_ST,     
                 }teAcessCtrl;
    Neither of those uses any memory because neither of them contains any variable declaration. Defining a macro says nothing about how you're going to store the values they define.
    You could for example store them in ints, or you could store them in shorts, or chars, or you could even store them in just two bits, by subtracting one from their value and packing four of these into each byte.
    It's the declarations of the variables and the code that loads and stores them that is important.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #20
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by itCbitC View Post
    Ain't I saying the same thing?
    Not really. You stated enumerators are run-time constants, in a manner that implied a distinction from compile-time constants.
    Quote Originally Posted by itCbitC View Post
    Not according to the ANSI std it's not which specifically states that enumerators are named constants of type int.
    The C standard says that. The C++ standard, on the other hand, only states that enumerators are of "unspecified integral type" of sufficent size to hold the value.

    However, both standards state that the type used to represent the enumerated type is implementation defined. (The C++ standard uses the words "underlying type", the C standard dances around that concept without using those words).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #21
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by iMalc View Post
    Neither of those uses any memory because neither of them contains any variable declaration. Defining a macro says nothing about how you're going to store the values they define.
    I'm not sure I agree with this. I may be wrong, which is fine, but here's my thinking:

    You are still defining a new type. There is a typedef there. That has to be kept some place. As such, that new type's definition should in my thinking be taking up some space. Now I suppose it's possible, that if you don't actually ever declare an instance of that type, that the compile optimizes it out. But it's my thinking that since you're declaring a new type, that new type must be kept track of some place.

    Whereas with macros, it's all just text substitution.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #22
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by iMalc
    Neither of those uses any memory because neither of them contains any variable declaration.
    I came to this conclusion in post #10. However...

    Quote Originally Posted by quzah
    You are still defining a new type. There is a typedef there. That has to be kept some place. As such, that new type's definition should in my thinking be taking up some space. Now I suppose it's possible, that if you don't actually ever declare an instance of that type, that the compile optimizes it out. But it's my thinking that since you're declaring a new type, that new type must be kept track of some place.
    That makes sense, and is consistent with what grumpy asserted in post #4. On the other hand, one of the arguments that Scott Meyers puts forth in item 2 of Effective C++, 3rd Edition in favour of consts and enums over macros is that the "use of the constant may yield smaller code than using a #define (...) because the preprocessor's blind substitution of the macro name ASPECT_RATIO with 1.653 could result in multiple copies of 1.653 in your object code, while the use of the constant AspectRatio should never result in more than one copy". If this is true, then it may well offset whatever could be gained from textual substitution of macro names with literals instead of defining an enum type.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #23
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by laserlight View Post
    I came to this conclusion in post #10. However...


    That makes sense, and is consistent with what grumpy asserted in post #4. On the other hand, one of the arguments that Scott Meyers puts forth in item 2 of Effective C++, 3rd Edition in favour of consts and enums over macros is that the "use of the constant may yield smaller code than using a #define (...) because the preprocessor's blind substitution of the macro name ASPECT_RATIO with 1.653 could result in multiple copies of 1.653 in your object code, while the use of the constant AspectRatio should never result in more than one copy". If this is true, then it may well offset whatever could be gained from textual substitution of macro names with literals instead of defining an enum type.
    Okay, but the example given here isn't say const int IDLE_ST = 0x01; It's an enum typedef. typedef's are just compile-time information.

    You are still defining a new type. There is a typedef there. That has to be kept some place. As such, that new type's definition should in my thinking be taking up some space. Now I suppose it's possible, that if you don't actually ever declare an instance of that type, that the compile optimizes it out. But it's my thinking that since you're declaring a new type, that new type must be kept track of some place.
    Sure it might add to the size of the pdb debugging symbols file, but there is no reason a typedef "has to be kept someplace [in the resulting executable]". No, .NET doesn't count either. Your sentence shows that you are generalising about all typedefs here, even something as basic as typedef char CHAR; Are you not saying what it appears you are saying or have you lost the plot completely?

    We still need to see some code to work out which takes up more memory. I assume it is important because you have a lot of these to hold in memory at once?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  9. #24
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by iMalc
    Okay, but the example given here isn't say const int IDLE_ST = 0x01; It's an enum typedef. typedef's are just compile-time information.
    I do not think that the typedef itself would require any space in the resulting object file. What quzah was referring to was that a new type (i.e., the enumeration) was defined, and this definition would take up some small amount of space in the object file generated, possibly unless no objects of that enumeration were defined.

    Quote Originally Posted by iMalc
    Your sentence shows that you are generalising about all typedefs here, even something as basic as typedef char CHAR;
    No, a typedef merely provides an alias for a type. In the case that we are talking about the enum is anonymous but for the typedef name.

    Let's get rid of that typedef since it provides unnecessary syntactic sugar. Let's define the enumeration as:
    Code:
    enum teAcessCtrl {
        IDLE_ST = 0x01,
        RX_ST,
        TX_ST,
        NO_ST,
    };
    Now, let us restate quzah's statements:
    You are still defining a new type. That has to be kept some place. As such, that new type's definition should in my thinking be taking up some space. Now I suppose it's possible, that if you don't actually ever declare an instance of that type, that the compile optimizes it out. But it's my thinking that since you're declaring a new type, that new type must be kept track of some place.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #25
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    Okay, though I do not see the connection between that and your assertion that I am "confusing default type sizes with the explicitly specified ones", since as you stated "explicitly specified ones" are actually vendor extensions.
    Cool beans! that's not what I meant and I apologize because I posted that in a hurry and perhaps came across like that. I was simply wondering if my posts had managed to confuse you in any way
    Quote Originally Posted by laserlight View Post
    It is quite obvious that even though the C standard does not specify that the sizeof an enumeration must be the same as the sizeof its underlying type, such a relation is natural, and as mentioned the C++ standard specifies this explicitly.
    IMO all that the C++ std is doing is explicitly stating what is implied in the C std.

  11. #26
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    Cool beans! that's not what I meant and I apologize because I posted that in a hurry and perhaps came across like that. I was simply wondering if my posts had managed to confuse you in any way
    Ah, no worries
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #27
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by grumpy View Post
    Not really. You stated enumerators are run-time constants, in a manner that implied a distinction from compile-time constants.
    Don't think I ever mentioned the enumerators to be runtime constants, only variables defined to be of that enum type.
    Quote Originally Posted by grumpy View Post
    The C standard says that. The C++ standard, on the other hand, only states that enumerators are of "unspecified integral type" of sufficent size to hold the value.

    However, both standards state that the type used to represent the enumerated type is implementation defined. (The C++ standard uses the words "underlying type", the C standard dances around that concept without using those words).
    Once again I think that the C++ std does a great job of explicitly stating what is implicitly stated in the C std.

  13. #28
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by quzah View Post
    I'm not sure I agree with this. I may be wrong, which is fine, but here's my thinking:

    You are still defining a new type. There is a typedef there. That has to be kept some place. As such, that new type's definition should in my thinking be taking up some space. Now I suppose it's possible, that if you don't actually ever declare an instance of that type, that the compile optimizes it out. But it's my thinking that since you're declaring a new type, that new type must be kept track of some place.

    Whereas with macros, it's all just text substitution.


    Quzah.
    As noted, typedefs are the compiler analog of the #defines ie they are both directives. A typedef is to the compiler what a #define is to the preprocessor, so they both do not take up any space.

  14. #29
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by laserlight View Post
    Now, let us restate quzah's statements:
    Quote Originally Posted by quzah
    You are still defining a new type. That has to be kept some place. As such, that new type's definition should in my thinking be taking up some space. Now I suppose it's possible, that if you don't actually ever declare an instance of that type, that the compile optimizes it out. But it's my thinking that since you're declaring a new type, that new type must be kept track of some place.
    My initial impression of that was that it made no sense. What is there to keep track of, exactly, except the names and the corresponding values? It's an int(eger type), not a new type (except in the "ooh it has a name" sense) after all. So, I have two versions of temp.c and the corresponding temp.s, created with gcc on MinGW with no optimizations.
    The first temp.c:
    Code:
    enum teAccessCtrl {
        IDLE_ST = 0x01,
        RX_ST,
        TX_ST,
        NO_ST,
    };
    
    int main() {
        enum teAccessCtrl foo;
        foo = RX_ST;
        return 0;
    }
    and the corresponding temp.s:
    Code:
    	.file	"temp.c"
    	.def	___main;	.scl	2;	.type	32;	.endef
    	.text
    .globl _main
    	.def	_main;	.scl	2;	.type	32;	.endef
    _main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$8, %esp
    	andl	$-16, %esp
    	movl	$0, %eax
    	addl	$15, %eax
    	addl	$15, %eax
    	shrl	$4, %eax
    	sall	$4, %eax
    	movl	%eax, -8(%ebp)
    	movl	-8(%ebp), %eax
    	call	__alloca
    	call	___main
    	movl	$2, -4(%ebp)
    	movl	$0, %eax
    	leave
    	ret
    The second temp.c:
    Code:
    #define IDLE_ST 0X01
    #define RX_ST 0x02
    #define TX_ST 0x03
    #define NO_ST 0x04
    
    int main() {
        int foo;
        foo = RX_ST;
        return 0;
    }
    and the associated temp.s:
    Code:
    	.file	"temp.c"
    	.def	___main;	.scl	2;	.type	32;	.endef
    	.text
    .globl _main
    	.def	_main;	.scl	2;	.type	32;	.endef
    _main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$8, %esp
    	andl	$-16, %esp
    	movl	$0, %eax
    	addl	$15, %eax
    	addl	$15, %eax
    	shrl	$4, %eax
    	sall	$4, %eax
    	movl	%eax, -8(%ebp)
    	movl	-8(%ebp), %eax
    	call	__alloca
    	call	___main
    	movl	$2, -4(%ebp)
    	movl	$0, %eax
    	leave
    	ret
    Yes, yes, toy example, etc. I have no doubt that declaring a nice big struct might put some information in the file (haven't done the test, not that motivated). But I would be surprised if an enum put anything like type information in the compiled result.

  15. #30
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    I do not think that the typedef itself would require any space in the resulting object file.
    Yep!
    Quote Originally Posted by laserlight View Post
    What quzah was referring to was that a new type (i.e., the enumeration) was defined, and this definition would take up some small amount of space in the object file generated, possibly unless no objects of that enumeration were defined.
    Nope! as enums and typedefs are the compile-time analog of the preprocessor #defines.
    A #define is to the preprocessor what enums and typedefs are to the compiler.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 01-13-2008, 02:14 AM
  2. Question regarding Memory Leak
    By clegs in forum C++ Programming
    Replies: 29
    Last Post: 12-07-2007, 01:57 AM
  3. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  4. reading files into memory
    By bobthebullet990 in forum C Programming
    Replies: 3
    Last Post: 11-30-2005, 03:39 PM
  5. Shared Memory - shmget questions
    By hendler in forum C Programming
    Replies: 1
    Last Post: 11-29-2005, 02:15 AM