Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ macros
I came across a problem that I was unable to solve, at least to my satisfaction...
 
The best solution I've came up with so far involves using a macro. (I know...)
 
IDE: Visual Studio 2012
 
void main()
{
    std::vector<int>; numbers;
    numbers.push_back(100);
    numbers.push_back(200);
    numbers.push_back(300);
 
    // I'm not typing all of this every single time...
    numbers.erase(std::remove(numbers.begin(), numbers.end(), 200), numbers.end());
 
    // Better, but still, no.. (Having to supply the type really brings it down.)
    Vector::Erase<int>(numbers, 200); // See below for code

    // Nice.
    VECTOR_REMOVE(numbers, 200); // See below for code

    // I wish... :(
    numbers.Remove(200); // Doesn't really exist...   

    // I also tried making my own list type which used vector internally.
    // That way I could create the member method as shown above.
    // However, it had issues, and was dropped in favor of the other methods.
    // It was also the most work, since I had to re\create all the functionality.
    // In it's defense, the resulting interface was really nice. (Think C# List<T>)

    numbers.clear();
}
 
namespace Vector
{
    // Erase
    template <typename T>;
    void Erase(std::vector<T>& source, T item)
    {
        source.erase(std::remove(source.begin(), source.end(), item), source.end());
    }
}
 
#define VECTOR_REMOVE(vector, value) vector.erase(std::remove(vector.begin(), vector.end(), value), vector.end());
 
 
This problem extends far beyond this one example, thankfully, Boost has saved me from much of it, however, many problems still exist.
 
The real question of this topic:
 
Is a macro okay in the above scenario, if not, can someone point me towards a better solution that works, and uses the same or less amount of code as my current macro solution?
 
What about macros like this?
 
#define FOR(var, iterations) for (int var=0; var < iterations; ++var)
 
FOR(i, 10)
 std::cout << "Hello World!" << std::endl;
 
I'm mainly using macros where snippets would probably work, however, macros produce less code 'visually' which makes for cleaner looking solutions, in my opinion.
 
Thoughts? Evil? Okay? Meh?
 
---
 
Note: I've searched Google, and most macro discussions mention logging\header guards, and math you shouldn't be doing with macros, none of the topics that I found addressed these types of solutions, and whether they were acceptable or not.
 
I'm actually undecided, that's why I'm asking for your advice on the matter, and perhaps, you guys can supply me with some other options that I've overlooked too. Big Grin | :-D
Posted 2-Dec-12 3:19am
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

First:
// Better, but still, no.. (Having to supply the type really brings it down.)
Vector::Erase<int>(numbers, 200); // See below for code
Vector::Erase(numbers, 200); // <-- This works well enough
 
I've got no problems with macros, but I would proably prefix something like FOR with something I can reasonably expect to be unique, like JDERT_FOR or something ...
 
Best regards
Espen Harlinn
  Permalink  
Comments
Joe_Dert at 2-Dec-12 9:30am
   
Thanks for the response. :D
 
With the first version, it can't always deduce the type under VS2012, which can be a problem with longer types(vector of vector of type, vector of map of key value pair).
 
As for the unique name for the "FOR" macro, could I perhaps place it in a namespace, or will it still pollute the global namespace, in either case, it's nice to know it's not a total abomination in the eyes of other programmers. :P
 
Thanks again. :D
Stefan_Lang at 3-Dec-12 9:16am
   
If you're having problems searching a *value* of a very complex type, then this raises the question why you search by value to start with. Comparing an entire instance of a complex object might be expensive. Wouldn't it be more performant and elegant to instead search by some kind of identifier, or just the key in the example of key/value pairs? Why would you want to compare the key and the value?
 
As for namespaces: no they do not affect macros. The only way to restrict the space that a macro name pollutes, is using it locally within a cpp unit. You can also define and undefine a macro within the same header to prevent it from interfering with anything coming after that header, but that wouldn't help for your purposes.
Espen Harlinn at 2-Dec-12 9:35am
   
Macros got a bad name when developers tried to emulate the work done with the NIH Class Library:
http://www.softwarepreservation.org/projects/c_plus_plus/library/nihcl
 
This was before templates were added to the language, so they used macros to implment typesafe containers, which was a neat trick if you got everything right, and pretty hard to debug if you didn't.
Joe_Dert at 2-Dec-12 9:45am
   
Yeah, there is a lot of hate, so it makes it hard to tell when you should or shouldn't use them. :)
 
(Same goes for a lot of programming practices, really.)
 
I think my use of macros is going to be fine, since I'm basically doing find\replace style operations with them, as opposed to trying to do the work of templates, etc,.
 
Even still, it's hard not to get carried away with them.
 
#define STR(source) std::to_string(source)
 
That would be a time saver, but, has to be macro abuse. ;)
Espen Harlinn at 2-Dec-12 9:52am
   
Have a look at The Boost Library Preprocessor Subset for C/C++:
http://www.boost.org/doc/libs/1_52_0/libs/preprocessor/doc/index.html
 
Macros are useful, but it's usually a good idea to think about your coworkers - will they understand your code? Or yourself in a couple of years ;)
Joe_Dert at 2-Dec-12 11:28am
   
Thanks, it looks like an interesting read. :)
 
I've been wanting to learn more about Boost, and meta programming with templates\macros, things of that nature, so, it looks it might help in that regard.
 
Anyways, thanks again for your responses, the advice, and the links, etc, I really appreciate you taking the time to help me out. :)
Nelek at 2-Dec-12 13:37pm
   
+5 for the nice explanations and good tips
Espen Harlinn at 2-Dec-12 13:38pm
   
Thank you, Nelek :-D
Nelek at 2-Dec-12 14:10pm
   
You are welcome :)
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

While there are exceptions in favor of using macros, the examples you've given are a definitive NO-GO! Here are the reasons:
 
1. Macros pollute the global namespace: if you intend to use them locally (i. e. within just one cpp unit), then neither the readability nor the safed time for typing are a good argument, as the locality pretty much nixes both. If not used locally, the macro names will be visible within the entire solution and may potentially conflict with other code, including third party libraries!
 
Example: I've once spent a full week due to such an error caused by a max macro (defined in one of the windows headers, no less!), because it blew up Microsofts implementation of std::vararray (which also has a function called max)
2. Macros are not typesafe, and generally hard to debug.
 
3. The examples you've given can easily be implemented as global functions, or template functions. Those would be typesafe and could be included in a namespace to avoid conflicts.
 
4. It's way too easy to introduce mistakes in a macro that don't immediately show up and instead will plague future programmers. Since the result of such mistakes will usually be impossible to trace back to it's cause, they will instead require a full-blown-code analysis.
 
5. Your reasoning is doubtful: personally I prefer the original explicit version, as I understand them and know precisely what they do. Even if I don't, the typesafety of their definition will liekly result in a compiler error when I don't use them correctly. The Macros however are unfamiliar - I have to trust they do what *I* believe what they do, and if they don't, then anything can happen. To avoid that, I have to look up the definitions, and understand them. And even then, if I make an error, the resulting error messages will likely not show me the actual cause! Nor give a hint how to fix it!
 
Conclusion: If you do a project all on your own, with no-one else involved, and you do not intend to ship it as a library for others, then do whatever you feel most comfortable with. If not, then save yourself and everyone else a whole lot of pain and avoid those unneccesary macros.
 
P.S.:
Think about the following question:
Can you write error-free code without access to a compiler?
 
If yes, feel free to use macros whenever you like.
If no, then any macro you write is bound to cause hard to fix errors.
 
Because writing macros is like switching off compiler syntax analysis.
  Permalink  
v2
Comments
Joe_Dert at 3-Dec-12 12:08pm
   
Thanks for the well thought out answer. :)
 
I do have some comments\questions.
 
1. Namespace pollution: I agree this is a problem.
 
Would changing the names help any? (ie, MACRO_STD_FOR(1, 100))
 
Then we have def\undef, which boost uses on it's macros, couldn't something like that be used to hide them away?
 
2. Type safety\debugging: Can't argue here.
 
I've already hit a few issues, though, keep in mind, I was intentionally seeing how far I could push them, what they could do, and couldn't do, etc,.
 
3. Global functions: I'm slightly confused.
 
Wasn't my first version exactly this? It was a global function, tucked away in a namespace. (ie, Vector::Remove) ???
 
At any rate, the main issue I have with this version, is that the IDE isn't deducing the type of the T parameter in many cases, forcing me to type it out.
 
It may not seem like a huge deal, but, these sorts of things pile up.
 
I also dislike the inconsistency of it visually, I'd have to always type out the type parameter to avoid this regardless of whether the IDE picks it up or not.
 
4. Impossible\Code Analysis:
 
I don't 100% agree here, though I do see your point, and the potential for problems with macros.
 
Here's the crux though, I test my code, and I'm not talking about the macro, I mean in general, so, if I make a change to my code I compile it, and test it, and if something went wonky out of nowhere, I can safely assume that I've isolated the problem to my last changes.
 
I realize that may not be ideal on HUGE code bases with multiple programmers, etc, but still, I'm fairly aware of my changes, what worked, and what didn't, so, even then I can reasonably narrow down the source of the issue.
 
5. Reasoning\Etc:
 
What's doubtful about my reasoning?
 
In some cases I was able to save over 50 characters. Typing 20-50 less characters per call is huge savings, you're obviously speaking from the: I get paid by the hour perspective. ;)
 
I assume by original, you mean the actual STL code, ie, the long version, correct? If so, then you should have NO issues with trusting my macro, seeing as they produce the same output.
 
The IDE literally performs a find replace operation, replacing my macro with the code you claim to trust.
 
I can't argue about it losing type safety, however, even the quickest of glances at the macro reveal how it works, and what it does.
 
If you trust the STL code, then you have to trust a macro based directly on it.
 
It's like saying you don't trust this code.
 
#define HELLO_WORLD() std::cout << "Hello World!" << std::endl;
 
I assume you don't use logging macros, or header guards, or BOOST_FOREACH, etc, etc,. ??
 
Look, I'm just saying, at some point, you have to admit you're afraid of the code boogeyman if simple macros like mine worry you that much.
 
Again, I agree, they do have issues, generally speaking about macros, however, mine are very simple, and quite clear in intent. (And honestly, why are using the macro, if you don't understand it.)
 
Sure, I use the STL without fully understanding what happens under the hood, however, I know what the function does, and in the same light, I know what my macro does. (I'm saying, you shouldn't be calling random functions you don't understand.)
 
So really, I'm failing to see the problem in this regard.
 
----
 
Anyways, I do appreciate your answer, and the time you spent formulating it, and don't take my harsher comments too personally, they're not intended that way, I just think you're being a bit over dramatic about some things.
 
To answer your last questions:
 
1. Yes, this is a personal project.
 
2. Yes, I write 'mostly' bug free code all the time, and as mentioned, I test thoroughly, and you'll rarely find a try\catch block in my code. (I simply think about every possibility, and account for it, occasionally, some slip through, but, meh.)
Stefan_Lang at 3-Dec-12 13:11pm
   
1. Yes, undef helps, especially if you have no #include between the def and undef. And yes, using longer, more unique identifiers for macros definitely helps, but it counters the benefit of less typing effort ;-)
 
3. Yes, your first version was indeed ok, I was just commenting on the macrofication step. The example should work without the type specifier, so I didn't understand your reason for using a macro. I've read your comment about type resolution only later. I agree, that is annoying.
 
4. I've been bitten too many times by these kind of bugs. Probably, with the intelligence of current tools and the verbosity of error messages it is now less of a problem than 10 or 20 years ago. But I rarely see the benefit of using a macro outweigh the risk of introducing such bugs.
 
Yes, if you change some things, and use version control, and you see odd things going on, the effort of locating the cause is restricted to just the most recent changes. However, half the time I encountered such problems they were hidden away in some third party header that got included some 5-8 steps down the dependency path - and that's a lot of gruelling work just to pinpoint! Note that when I say the problems were hidden in that header, the header itself was in fact fine - it was just some macro introduced months ago (or by some other third party library) that caused that header to explode, e. g. because it got included in a different order than before.
 
The problem I pointed out under item 1. above is a perfect example: MS shipped both the incriminating windows header defining the max macro and the implementation of std::valarray, without even noticing the problem! It was only when I tried to create a windows project that uses valarray when everything came tumbling down! Just because the order of includes didn't match what MS expected (or tested).
 
Yes I didn't have a lot of code to analyze, but it never occurred to me (until much later) that the problem wasn't in my code at all. So I still lost a lot of time figuring out what happened.
 
5. saving on your typing effort is not a good reason to start with: modern editors with auto-complete safe you most of the work; C++ 11 lets you use the keyword auto to safe you typing out a result type; plugins like VisualAssist, and Power Tools help greatly in your work. But, most importantly: the time you spend typing code is neglectable compared to the time you spend testing, debugging, and fixing your code! You should always strive to minimize that effort first, and I've found macros tend to increase code analyzing and debugging times - often by a considerable amount.
 
As for your Hello World define: I can easily think of a use that will even compile, but do some nasty things at runtime. At the very least you should enclose your code in braces: that will avoid a whole lot of problems (and cause your compiler to cough more often if that macro isn't used as you intended).
 
As for logging, I'm using a class. And in the projects I work in, we're currently not using boost, but I'd trust the macros defined there, as they're very well documented (and yes, I've read that documentation!), and they are used for very good reasons.
 
I do use include guards. And I use conditional compilation for debug code and OS-dependend stuff. But that is about the extent that I use preprocessor symbols for. It may be radical, but less typing is not a sufficient argument for me, nor have I found another argument to use macros in the projects I've done. Instead I use constants, typedefs, template functions and template classes. And if the latter get too complex to use, I introduce helper functions that do away with most of the tricky stuff.
 
That said, my current project has several million lines of code, and >90% of that code wasn't written by members of the current team, so I'm pretty happy that macros are generally not used. I suppose in a small project, especially one you do by yourself, you'll have different priorities.
 
Finally I'd lik
Joe_Dert at 3-Dec-12 13:48pm
   
It seems it cut you off at the end.
 
Regardless, as stated, I mostly(99%) agreed with you to begin with, but, I appreciate the clarifications, and additional answers, etc,.
 
As for the Hello World example, I'm sure you could make it blow up, but, you'd have to misuse it in order for that happen.
 
If you can show me an example of that macro being used as intended.
 
Example:
 
int main()
{
HELLO_WORLD();
}
 
And having it blow up, I'd be quite surprised.
 
Sabotaging code is easy, I can make plenty of valid C++ code blow up, that doesn't mean we should remove the offending features from the language, or not use them, etc,.
 
std::vector test;
test.push_back(100);
 
for (int i=0; i < 2; ++i)
test.at(i);
 
Output = KABOOM!!!
 
Is that a failure of 'for' or 'std::vector' perhaps we should stop using both of them just to be safe. :P
 
Seriously though, 'for' doesn't know any better, but, 'std::vector' should have caught this, tsk, tsk,.
 
---
 
We've also failed to acknowledge some benefits of macros.
 
For example, there is no overhead from calls, since the code generated by a macro happens in place. (ie, VECTOR_REMOVE has no call overhead, Vector::Remove does.)
 
That could really make a difference in some cases. (Large loops, complex code, etc,.)
 
Also, it removes the need to write out templates, creating Vector::Remove took more code than VECTOR_REMOVE. (This can really add up, depending on complexity of the function you are macro-izing.)
 
Lastly, you can create code of nearly any complexity, you can make a "unit test" macro that can create code based on parameters for testing purposes. (I've tried this, it works.)
 
No other C++ method I'm aware of can do this, and it's very useful for testing.
Stefan_Lang at 4-Dec-12 5:37am
   
The cut-off part was just me pointing out that I appreciate the discussion, as questions about the use of macros too often turn religious (i. e. flame war).
 
In any case, my argumentation was mainly from the experience of large scale projects, and you don't need to take everything all that seriously if you're doing just a small, personal project.
 
As for using macros, my point was about the chance that someone (other than you) could be using it in a way that you *didn't* intend. Typesafe functions can be defined in a way to blow up at compile time if used in the wrong way, but macros may either blow up at runtime, or generate compiler errors that are hard to locate. Neither is a real issue in personal projects though.
 
Your point regarding overhead of function calls should consider two things:
1. can the call be inlined?
2. even if it cannot be inlined, is the performance overhead actually an issue? Usually 90% or more of your code is not relevant regarding overall performance, so it doesn't matter if you have some avoidable extra function calls. You won't notice that your code takes 0.0003s longer to respond. Function calls don't really take much time unless you pass complex objects by value, so the usual way to avoid overhead is pass those by (const) reference instead.
 
I understand and agree to your unit test argument: use cases and test cases are often pretty much the same, so it makes sense to use macros for both if that speeds up your code generation. Same for alternate scenarios. That is not actually complex code to begin with, so the chance of introducing unwanted issues is much smaller.
Joe_Dert at 5-Dec-12 12:09pm
   
Thanks, I enjoyed the discussion myself.
 
I like to understand how things work, and why, and this stretches beyond programming concepts, into the choices made by programmers as well as in general aspects of life itself. :)
 
I absolutely loathe people who do it by the book, simply because the book told them to. (Even if it's correct, it's a bad way to operate.)
 
This is how we end up with so many incompetent people in so many fields. (Amongst other things.)
 
Sometimes you have to throw the book out, and you can't do that if you don't understand the underlying issues.
 
That's why I refuse to accept such simple answers as: Don't do that!
 
Why? When?
 
You can't formulate the rules outside of known areas of experience unless you understand these concepts.
 
If I were to tell you killing is wrong, absolutely, and then you find yourself in a position where you're forced to defend yourself, or your family, etc, that reasoning no longer holds up to the reality of the situation.
 
It becomes a gray area, where you're forced to think for yourself, and I'd much rather be armed with real knowledge than fortune cookie wisdom dished out wholesale by some dude I've never met in my life.
 
Anyways, after much toiling, and trial and error, the best solution I could come up with was a mixture of 1) and 4) from my original posting.
 
I have the external Vector:: functions in case I need to work with a std::vector directly, and I've also recreated my List class using those methods internally.
 
Whatever issue I originally had with method 4) was solved during the rewrite, it now works as expected.
 
It's a bit of overhead, and I'd prefer to NOT do it this way, but, this provides me the cleanest interface for working with std::vector.
 
Examples:
 
List list;
list.Add(100);
list.Add(200);
list.Remove(200);
list.ForEach(...)
list.Where(...)
list.Clear();
 
Etc, etc,.
 
It's design should be fairly efficient since I'm really just hiding some details of working with std::vector, it may be slightly less performant, but, I doubt it's enough to even matter. (I'll profile it with Shiny, to be sure.)
Stefan_Lang at 6-Dec-12 5:31am
   
'Following the book' is good as long as you don't have first-hand experience, and as long as you do question it's merits. I've seen lots of articles and books that offer good advice, generally speaking. But that same advice often breaks down in more complex situations.
 
Learning isn't about memorizing rules, it is about understanding where they come from, so you know when to use, and when to abandom them.
Joe_Dert at 6-Dec-12 12:06pm
   
"Learning isn't about memorizing rules, it is about understanding where they come from, so you know when to use them, and when to abandon them."
 
Exactly.
 
My point, was that I appreciated our conversation, because it was much more constructive to that end.
 
It's like the old saying:
 
Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime.
 
That's my approach to learning, I'm always trying to learn to fish. :P
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

Why don't you inherit vector and implement Remove function(that you so want). That would be one way of going about it.
  Permalink  
Comments
Stefan_Lang at 5-Dec-12 4:34am
   
That is certainly a possibility, but certain operators (e. g. essignment) can not be inherited, and would need to be re-implemented. That's a whole lot of work for just one function.
Aswin Waiba at 5-Dec-12 4:41am
   
You could always inherit like
class ClassName: public vector{
public:
using vector:operator&();
//and so on
};
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Try to avoid using macros. It is really bad habit. Anyone can argue about lots of macros used in MFC, ATL, boost and other places. But with using macros in most cases the code looks really bad and evil, and tends to become unmaintainable. Especially for making a better vector.erase or a better for(...) loop, is really NOT better. This is NOT a good example of using macros. There are lots of algorithms in STL which you can use instead. By the way, algorithms do not use macros.
 
If there is some good way to avoid macros, do NOT use macros. If you would like to make short expression shorter by using macros, then do NOT use macros. If you intend to use macros, do NOT use macros.
 
Usually macros is used for
1. Making some portable constructions, which may be platform and compiler dependent. In this case it is used with conditional compilation.
2. Avoid really big and bad sequences of code which are needed to use often. For instance different forwarders, handlers, callers, generators.
3. Creating some constructions which are not supported by compilers, for example such as lambdas or some kind of persistence, weird initialization sequences and so on
4. Creating aliases for magic constants, to avoid the magic in the code and make it more understandable. For instance S_OK instead of 0, or DISPID_GETDETAILSSTATE instead of 19 Smile | :) . Anyway here C++ offers better ways, such as declaring constants, and enumerations, with compile time control of the type.
  Permalink  
v2
Comments
armagedescu at 4-Dec-12 7:06am
   
For the vector.erase I do NOT see any problem to solve. Everything work just fine and just neatly, there is NO problem to solve.
Second problem. If you work in C++, please do not think in C#. Working in C++ means thinking in C++, so forget C#. Don't compare with it. Do not try to do C# in C++. Do not translate C++ into C#. Try to find the C++ way with working in C++, and only after that you will feel the power of C++. Yes, C++ is a more capricious language than C#. Yes, it does not forgive mistakes. Yes, it does not keep you away from making mistakes. There is a complete freedom of making mistakes as well as full freedom of making good code. Don't think in macrosses. It is not the right direction to investigate for becoming a good C++ programmer.
Before talking about lacks of STL, you first have to become at least STL competent. But as I see, you are not such an STL expert.
About using goto, you should keep in mind, that you are using C++, not ASM. C++ provides lots of good possibilities for not using goto. ASM does not have them.
And about thinking line. The thinking line of ignoring good advises from lots of experienced people, working in C++ for many years, is the mark of dilettantism.
Anyway, it is up to you, to take good advises in consideration or to ignore them. After getting some more experience, you will understand, will feel that we say, and will find the right way. But this will be very painful process for you with such a ignorance.
armagedescu at 6-Dec-12 10:47am
   
>>>>>No it doesn't, it provides syntactic sugar
ASM programmers uses jumps mostly (99%) for simulating EXACTLY the same syntactic sugar. Moreover, many of ASM programmers uses lots of macros to wrap the jumps to some kind of that syntactic sugar.
 

>>>>>And I don't need to be an STL expert
Be sure, you are not.
 
>>>>source.erase(std::remove(source.begin(), source.end(), item), source.end());
std::remove is optimized for fast working directly in memory.
 
Look at this code, which does not use any vectors, lists, containers, just memory:
///////////////////////
int* z = new int[100];
for( int i = 0; i < 100; i++) *(z + i) = i % 5; //initialization
int* end = std::remove(z, z + 100, 4);
for(int* i = z ; i < end; ) cout<< *i++<< " ";
z = realloc(z, (end-z) * sizeof(int)); // readjust memory
cout<< "--- finish z ---" << endl;
 

//////////////////
std::remove is just algorithm, and it knows nothing about what is there, memory range, vector, any kind of memory container. This can be a string or anything else. The end operation of vector.erase is just adjusting of the vector size after ending of operation.
You can do lots of std::remove operations, without readjusting the size. And readjust the size only once, only after the end of all removes. While doing lots of operations this is a really big optimization. Can you do this in C#?:
int* z = new int[100];
int* end = z + 100;
for( int i = 0; i < 100; i++) *(z + i) = i % 5;
//lots of changes in memory:
end = std::remove(z, end, 4);
end = std::remove(z, end, 3);
end = std::remove(z, end, 2);
//readjust only once after finishing the whole work:
z = (int*)realloc (z, (end - z) * sizeof(int));
for(int* i = z ; i < end; ) cout<< *i++<< " ";
cout<< "--- finish z ---" << endl;
 

Yeah, and exactly the same thing, but with vector, fast, robust, and no unneded operations:
std::vector x;
for( int i = 0; i < 100; i++) x.push_back(i % 5);
std::vector::iterator ite = x.end();
//many memory operations
ite = std::remove(x.begin(), ite, 4);
ite = std::remove(x.begin(), ite, 3);
ite = std::remove(x.begin(), ite, 2);
x.erase(ite, x.end()); //readjust only once
for(vector::iterator i = x.begin(); i != x.end(); i++) cout<< *i<< " ";
cout<< endl<< "---- finish vector ----"<< endl;
 

 

>>>>#define _VICONT(it) it._Getcont()
>>>>#define _VIPTR(it) (it)._Ptr
These definitions are not for you. They are for STL internal using only, and are used for advanced debugging, when is defined some more advanced debugging level. None of C++ standards for STL provides such a macros to the user. And none of programmers uses these definitions to make their projects. No STL implementations provide them to the end user. Don't focus on C#.
 
>>>>>I've written several external functions:
O sorry, you've done such a big performance, you've written several function!!! :) Sorry man, but do something smart before talking too much about you've done.
 
>>>>>This is the reason libraries like Boost exist
Yeah, boost is good, but using it noes not give you so much advantage. This is why many big C++ projects do not use it. Most of C++ applications which have large usage over world, do not use Boost. This is not due to the fact that experienced C++ programmers do not know boost. This is due to the fact that Boost really do not provide such a big advantage. STL is far enough, for people that know it. But for specific tasks as maths, image processing, compression, regular expression, xml processing there exists lots of other libraries. So, STL is not a constraint at all, for people that knows it. It is used everywhere.
armagedescu at 7-Dec-12 3:38am
   
Assembly is the language, and everyone programs in Assembly, but not in Assembler. The Assembler is the compiller for that language. Assembler assembles machine language object files from assembly language. And after that object files written in any languages are linked with a linker, into an executable dynamically linked or standalone module.
The assembly language mnemonics are translated each one directly into machine language instruction. So, there is thery little difference. Assembly language is exactly the same machine code, but written in a human readable style. Nothing less and nothing more. And even if some programmer written directly in machine code, that programmer kept jumps in such a way, that is simulating same sintactic sugar from higher language.
If you would have any idea about machine language and assembly you would not say such stupidities. But you are complete null in programming, and of course you have nothing to respond. You have trapped yourself in your own arrogant stupidity and trolling. No one here obligated you to tell such stupidities. Of cource, you have now no way back :)
 
>>>> Machine code is founded on the equivalents of goto, everything from
>>>> loops, to simple
>>>> "if" statements, and function
>>>> calls, are roughly the same thing as goto.
Yes, exactly, jumps are used to simulate the same conditional, looping, calling statements, which are not provided by ASM but are provided by higher level languages more than 99% of cases. You can verify yourself. Before doing that you have to know that assembly language is. But as I can see you are very likely to fail learning it.
 
A, yes, as I can see, your last response contains nothing about STL :) You really ran out of any arguments. All the rest is just trolling.
armagedescu at 18-Dec-12 5:56am
   
>>>>> Assembly language is just a standard, assemblers generate code that meets this standard, as does C++.
Aa, yeah, you've just discovered America
 

>>>>> But, okay, Boost is WAY better, so much so, that Boost is being added to the STL and treated as the new STL in C++ programming.
I reiterate that I said. You are not Bjarne Stroustrup. Before copypasting some opinion from the internet as yours, you should at least know that you are talking about. You do not know STL, and Boost neither.
Boost is not a replacement for STL. There are added some new functionalities, but old ones remains 99% the same. And no one replaces the other. STL is meant to feet the needs of high level programming, and also to feet the possibility of low level fine tuning, when working just in C style. You can refer the sample of code written above.
 
>>>>> That's why the STL sucks, code, is code, is code, no matter what the language.
Before talking about STL you have at least to know it.
 
>>>> If C# can do this in 2 lines of code, why can't C++\STL?
C++ is other language, having its advantages. And advantages of C++ makes it to be used and developed, even if some languages are easier to use. This is why most of widely used applications are made in C++. And this is why tons of killers of C++ that appears over decades, haven't yet killed even a millimeter of C++. Moreover, C++ is still being developed, modernized and prepared for using in the future.
In C# some things takes less code to write, because lots of libraries written in C++ which it uses. Without these libraries, you would not even be able to open a file in C#, or to resize an array.
 
>>>>>>>>> So, we have two languages, in the end, both accomplish the same\similar task,
>>>>>>>>> but one does it faster(RAD), with better syntax, less errors, etc,.
Not everything in the world is RAD. C++ is used because of other advantages. What browser are you using?
 
>>>>>>>> That's it, I don't care what you think, C# is better, and C++ has no excuse,
>>>>>>>> code is text, it gets read, tokenized, interpreted and compiled.
This is why C# is written on the top of C++. And this is why C# provides bridges to C++, and makes you able to interact with native C++ modules. This means C# is not universal, and provide possibility to be enriched by help of C++.
 
>>>>> Much like a macro, when creating a language, you can make the code anything you want, I could write a function:
C++ provides enough flexibility to make abstractions without using macro. Don't start from macro, this is not that you need to become a good C++ programmer. Trust me. I can not prove that, but any C++ programmer will tell you the same.
 
>>>>> void DoIt();
>>>>> That compiles to an entire game, it's called abstraction, and C++ really needs to learn how to use it.
Yeah, and for each small modification you will need another DoIt
void DoIt1(); will do it, but in red color
void DoIt2(); will do it, but with round movements
So, for each small new requirement in the game you will need other DoIt, but with small difference than the other. After making many DoIts you will see the need of making some extended DoIt, like DoItEx. But after some more time, you will notice that you develop full STL and all your DoIts are part of an archive which you intend to use widely, but will never do it, as you did not do it for long time already.
 
>>>>> For the record,
For the record, I work as C++ and ASM programmer since 1999. But know them since much earlier.
 
>>>>> I know various languages x86 ASM(reversing),
I don't want to show my full profile here, because it would take more place than whole text written above. But I only will tell you that I have deep background in diverse technologies, including C#/C++/Java/Perl and many other technologies.
armagedescu at 18-Dec-12 6:04am
   
---ups, text got trunkated.
 
>>>>> I'm not a master of them all,
>>>>> Stop telling me I'm not.
Please stop trying to impress people. You would better trust good advises from experienced programmers until you get deeper understanding and knowledge of the technology.
armagedescu at 19-Dec-12 3:11am
   
>>>> C# code compiles to IL, the JIT compiles the IL to
>>>> machine code at runtime. (The newest C# compiler Roslyn is written in
>>>> .Net too, likely, C#.)
>>>> http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx
So what? There are lots of technologies doing that. Is not only C# and Java.
 

>>>>>> There are very few real advantages to using C++.
>>>>>> 1. Cross-Platform Support
The portability is not the strongest point and the real advantage of C++.
 
>>>>> You can expose ofstream\ifstream for flexibility, and STILL provide high level functions in the STL.
You've just discovered America
 
>>>>> You really need to work on your English.
With you I don't speak english but I speak C++. This is why I work with british, french, japanese, german, ... programmers and we all understand each other. By the way, how many languages do you speak?
 
>>>>> C++ could easily ADD these new functions using the STL streams.
>>>>> std::write_file(path, text);
>>>>> std::read_file(path);
>>>>> How would that hurt C++?
What for? There is no need for that. And if appears the need, is not a very smart thing to add small wrapper what will do that in the application. It does not make much sence to add them to standard library.
 
>>>>> I know various languages x86 ASM(reversing), C\C++\C#\Python\Perl\Basic,
>>>>> and numerous scripting languages from my game modification days,
>>>>> NWScript, Morrowind\MWSE, Oblivion\OBSE, Skyrim\SKES\Script Dragon,
>>>>> and various other game related scripting languages, etc,. (Also, JS\HTML\XML, etc,.)
So what? Trolling again? A lot of people suck at their job and have been doing with lots of technologies
armagedescu at 8-Feb-13 11:03am
   
Hey, there is not about reading comprehension, there is about programming skills, which is far not your strongest point.
About Java, you big fail, because byte code is compiled just in time (JIT), and is more than ten years since java does that.
About German\Japanese\French you again missed the point. I don't know how many languages do you speak, but it does not amtter, because we are talking C++, which like any kind of programming is far not a strong point of you.
 
BTW, I don't know if "Epic Fail" in your signature is your alias or your real name, but it describes very well yourself and your programming skills.
Joe_Dert at 8-Feb-13 20:11pm
   
You can call me a bad programmer all you want, it doesn't change reality.
 
This whole thing goes back to you claiming that I should NEVER use macros, but, the best programmers in the world use them, nearly every C++ API in existence uses them.
 
Look at your answer, has it been upvoted?
 
No, it hasn't, no one here agrees with you, and the LIBS speak for themselves, Boost, C++ itself, DirectX, etc, they all use macros.
 
You were wrong, accept it.
 
You can change the subject all you want, but, you were wrong, okay?
 
I'm going to stop talking to you now, because, well, you're a moron.
armagedescu at 12-Feb-13 4:23am
   
I've made a search to find where I claimed "never", and I found only one occurence. And this occurence has nothing to do with macros. So, don't attribute to me things I did not say. Moreover, I've used macros many times in different projects. And also used them in a public project, placed on codeproject. These are very specific usages, it is not your case. Macros was never replacement for implementation.
About upvoted answers, take a look. No one advised you to use macros. Keep in mind, all suggested solutions there have no macros.
About Boost, DirectX, MFC, ATL or anything like that. You are not author of any of them, so don't tell who agrees and who not. Ask any of authors of that libraries, and all of them will tell you to not use macros, at least in the way you are using them. Yes, there are some very specific tasks when better to use macros, but this is not your particular case. In your particular question, this is good only for practice in writing macros, but nothing more.
Joe_Dert at 18-Feb-13 14:21pm
   
"I've made a search to find where I claimed "never", and I found only one occurence. And this occurence has nothing to do with macros. So, don't attribute to me things I did not say. "
 
Really?
 
"If you intend to use macros, do NOT use macros."
 
This statement is a direct quote from your original post.
 
If you actually understood English, you would know that this statement in English IS the DIRECT equivalent of saying "never use macros"...
 
---
 
"About upvoted answers, take a look. No one advised you to use macros."
 
Really?
 
-Quote-
 
I've got no problems with macros, but I would proably prefix something like (the macro) FOR with something I can reasonably expect to be unique, like JDERT_FOR or something ...

Best regards
Espen Harlinn
 
--Quote--
 
This guy said that he had no real problems with my macro implementations, and he's a CodeProject MVP, with a much higher reputation than you.
 
So, again, you're wrong, someone did say it was okay, and it was upvoted several times, btw...
 
----
 
"About Boost, DirectX, MFC, ATL or anything like that. You are not author of any of them, so don't tell who agrees and who not. "
 
I don't care what the authors say, I've seen their code, and all of these LIBS abuse macros for various purposes.
 
It all boils down to holier than thou "do as I say, not as I do" bull crap, they're nothing but hypocrites if they 'do' indeed claim I shouldn't use macros as you've stated.
 
-------------
 
Finally, if you actually had kept up with the discussion, you'd have noticed, I decided against using these macros long ago.
 
So, you've been calling me stupid for a month(?) because I used these macros, and ignored your advice, blah, blah, except, I didn't actually use them(the macros).
 
Actually, my decision had nothing to do with your horrible, horrible answer, or the retarded conversation that followed, in fact, I decided this long before our discussion took place based on the GOOD advice of "stefan lang".
 
You could learn a lot from him.
 
The point of our discussion was simple:
 
I'm telling you, that you give bad advice, in an arrogant manner, and no will upvote you, and no one will like you, or listen to you because of this.
 
And you've done NOTHING but prove me CORRECT with every single post you've made since.
 
I was trying to help you, but, you're obviously never going to "get it", so, as I said before, we're done.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 8,149
1 Sergey Alexandrovich Kryukov 7,287
2 DamithSL 5,614
3 Manas Bhardwaj 4,986
4 Maciej Los 4,910


Advertise | Privacy | Mobile
Web04 | 2.8.1411023.1 | Last Updated 5 Dec 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100