![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#21 | |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Quote:
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
|
#22 |
|
Professional Programmer
![]() Join Date: Sep 2005
Posts: 419
Rep Power: 4
![]() |
>I feel you have misinformed people in your previous set of comments.
How you feel is irrelevant. I deal in facts, not feelings. >I feel it is only confusing people since you keep trying to find flaws in my comments and examples. If I point out a flaw, it's because there's a flaw. I have nothing against you personally, even though you seem to be taking my comments personally. >There is nothing wrong with casting the return value of malloc In C++ the use of malloc is suspect from the start because it doesn't play well with objects. However, in C++ the cast is required due to C++'s beefy type safety compared to C, which is why I let that slide as we're in the C++ forum. In C, there's most certainly something wrong with casting malloc. It hides legitimate errors. It also makes maintenance more difficult. In C, you shouldn't be casting malloc and in C++ you shouldn't be using malloc. This is my point, take it as you will. >In most cases the compiler complains that it does not know what type of pointer this is. In all cases for C++ because there's no implicit conversion from void* to T*. In C this conversion is supported. >Since malloc returns a value of type (void*) which is a generic pointer (its >size depends on the machine you are working with. ie: IA32 will have 32bit >wide pointer. IA64 will be 64 bit wide) it should be cast when assigning to a pointer. That's probably the most creative load I've seen someone pull from their posterior regions in a while. Do you even know what you just said? >C++ has often been described as a federation of languages which includes C. Hmm, that's the first I've heard of it, and I like to think that I've had a little bit of exposure to C++. >Anything you can do in C is ok for use with C++. Really. Why doesn't this compile in C++ then? #include <stdlib.h>
int main(void)
{
char *new = malloc(10);
return 0;
}Yes, in C++ the cast is required because an implicit conversion from void* to T* is not supported. It works fine in C. That's not at issue. Remember that I said I'll let slide the fact that you cast malloc because I'm assuming you're talking about C++? I didn't say you were wrong to cast malloc, I said you were wrong to use malloc in the first place. >sizeof(char) may always be 1, but this is an example of best practices. No, sizeof(char) is always 1. Guaranteed. The C standard and the C++ standard state in no uncertain terms that sizeof(char) is absolutely, positively, until the heat death of the universe, 1. Failing to understand that in your code is not an example of best practice, it's a big honking red flag that screams "DO NOT TRUST ANY OF THIS CODE!". >Also, when reading code, code examples, etc- you must assume that a label >such as "lengthofstring" is intended to represent the length of the string. Just like I'm to assume when reading sizeof(char) that you're using "best practices" rather than just being an idiot? It takes a stupendously foolish person to take something like "lengthofstring" at face value. Lengthofstring could mean at least two things, and the name of the variable is hardly enlightening. >I believe it a good habit to set your memory to null first before using it. If you're going to write immediately into it anyway, why? You're just adding overhead by copying to memory twice. >Also, memcpy is more efficient then strcpy and is safer. Heheh. Well, I'll take off my implementors hat and assume that I haven't written those two functions for a commercial implementation before. memcpy is only safer if you get the size right. But if you get the size right in allocation, strcpy is perfectly safe. In fact, for initializing strings, it's safer because you're less likely to forget to tag on a null character. memcpy is far from more efficient if you use memset first. Even if you do the right thing and tag a null character after memcpy runs (assuming you got the tricky size calculations right), memcpy is still less efficient than strcpy when taken at face value because strcpy does less work. When optimized, the difference between the two is hardly noticeable, but strcpy still wins out due to the opcodes that it can take advantage of. Or are you unfamiliar with how the two functions are optimized in assembly? >You would have to use a different function than strcpy to do this. So, are we caring about the rest of the world before we write this code or as an afterthought? In my experience, internationalization is best designed into the code from the start, in which case neither strcpy nor memcpy would be considered. Especially in C++. But for existing code that needs to be updated for the international circuit, it's best to use specialized string operations instead of general solutions because they're optimized for strings. You get a better and cleaner result. >I carefully chose the name "lengthofstring" so there would be no confusion for what the value represented. Be more careful next time. By "lengthofstring" do you mean the number of characters in the string, excluding the null character, or the number of characters in the string, including the null character? Both are perfectly valid choices and assuming either will fail miserably if the assumption is wrong >if there is a code example that makes it obvious what different labels >represnt, do not assume that they contents are malformed or incorrect. I agree. It's best to trust the original author unless you have good reason not to. But this isn't one of those cases because your label doesn't make it obvious what is represented. >this article is interesting- but unfortunately does not answer the question that I had raised Then the question you meant to ask wasn't the question you actually asked.
__________________
Even if the voices aren't real, they have some pretty good ideas. |
|
|
|
|
|
#23 | ||||||||||||
|
Newbie
Join Date: Oct 2006
Posts: 16
Rep Power: 0
![]() |
Dawei:
Thank you yes, for pointing this out. I made a big mistake by saying C code is 100% compatible with C++. I have started another thread for this discussion regarding the example that you mentioned. Narue: Quote:
Quote:
Quote:
Quote:
Quote:
I spoke too quickly with that statement- I was wrong. C code is not 100% transferrable to C++. Most of how C++ works is borrowed from C, and the point I failed to make was that there is no huge difference between C and C++ at the language level. So yes, I concede on this point. Quote:
Quote:
Quote:
Quote:
Quote:
Even if you do the right thing and tag a null character after memcpy runs (assuming you got the tricky size calculations right), memcpy is still less efficient than strcpy when taken at face value because strcpy does less work. When optimized, the difference between the two is hardly noticeable, but strcpy still wins out due to the opcodes that it can take advantage of. Or are you unfamiliar with how the two functions are optimized in assembly? I wrote an app which writes "TEST" using memcpy and strcpy and compiled with gcc: memcpy: real: 0m12.495s user 0m1.077s sys 0m0.000s strcpy: real: 0m5.881s user 0m5.124s sys 0m0.015s Both applications copy 5 bytes 123,456,789 times. Quote:
Quote:
|
||||||||||||
|
|
|
|
|
#24 |
|
Professional Programmer
![]() Join Date: Sep 2005
Posts: 419
Rep Power: 4
![]() |
>If these opinions are fact, please share your sources.
Give me a list of the "opinions" you're talking about and I'll provide my sources. I'm having trouble figuring out what your problem is with my comments, as I've been careful to explain the why as well as the what. >I said: <snip> That's what I thought you said. Clearly you don't realize that the size of a void* is irrelevant to how you can use it. >Credit to scott myers, who explains C++ this way in his book Effectice C++. Okay, though one occurrance hardly counts as "often". I'm also disinclined to interpret "View C++ as a federation of languages" as "C++ is a federation of languages". One describes a convenient perspective, the other implies a hard fact. I'll concede the point that it's been said, as I haven't had time to read the third edition carefully yet. >First: One thing you can't do in C or C++ is, misuse reserved words. new is a >reserved word in C++ and not in C. So, was that a mistake- because it didn't prove anything. Quite the contrary. It proved that perfectly valid C fails to compile as C++, which is a direct contradiction to your claim. >So yes, I concede on this point. Very well, I won't mention it further. >Please share with me, if this is not an opinion. Perhaps you should read the books you cite. Effective C++, second edition, page 19. >My point of best practices is: when allocating memory, its the number of elements * the size of the elements. I agree. In fact, I agree so much I'll show you a better way to use malloc that matches your best practice and my time tested conventions: p = malloc ( n * sizeof *p ); People learn from examples. Wouldn't you rather they learn from good examples than from sloppy examples? >It is my opinion that everyone should initialize their memory and variables- >but more so for people who may not keep track of what has/hasn't been initialized. In this our opinions differ. I would rather have people follow a methodical approach that includes paying attention to what they're doing rather than blindly initializing everything. Better code, and a better understanding of that code, results. >Although you hate it- I do it. I don't hate it, it's a good hedge if you don't want to worry about inserting '\0' in the right place. I also don't care if you do it. If it helps you write robust code, more power to you. I just think it's unnecessary. But that's from the perspective of my own skills, and because I'm such a perfectionist, I'm probably expecting too much of you. Please don't see that as a condescending statement, by the way. It's not meant as such. >What if I accidentally forget to allocate the 1 byte necessary for the null character? Then I get a non-null terminated string. And you think the same problem doesn't exist with your memset/memcpy trick in that case? >Both applications copy 5 bytes 123,456,789 times. That looks about right for a basic test. The two are identical for all practical purposes. In case you were wondering, the difference you saw is due to bleedover from other processes running on your system. If you ran the test again, the opposite result would be just as likely. So from a performance perspective, it's silly. How about from an intentional perspective? memcpy is for copying non-string data, but you're using it for strings. Wouldn't strcpy display your intentions far better? >I can't stress enough how this is an example and you should read it as one. A lot of really bad code has been written based on sloppy examples. >That article doesn't mention dynamically allocated arrays. It doesn't have to because that's a specific case of the general concept.
__________________
Even if the voices aren't real, they have some pretty good ideas. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| c strings in an array problem | monkijunki2 | C | 6 | Nov 15th, 2005 11:42 AM |
| How to make an array of pointers-to-char point to strings | aznluvsmc | C | 38 | Sep 21st, 2005 8:45 AM |
| Installing IPB 2.03 | bh4575 | Other Web Development Languages | 0 | Apr 23rd, 2005 3:36 AM |