|
Suspicious Dish posted:That's a respectable idea, but the problem is that the C preprocessor isn't simple, already. A more powerful language that compiles down to C and that doesn't bill itself as a "C preprocessor;" maybe even something project-specific: https://github.com/bkerley/chimichanga/blob/concatenative/pre2c.rb C code:
C code:
|
# ? Sep 19, 2012 16:59 |
|
|
# ? May 17, 2024 01:33 |
|
Just came across this PHP behavior (which confused the hell out of me), and it is apparently, according to the PHP dev, by design. Is there an actual justifiable reason for that, or is it just another example of PHP being PHP?
|
# ? Sep 19, 2012 17:34 |
|
Old-style constructors are deprecated, and it was a chance to start removing them entirely without breaking backwards compatibility. It's confusingly inconsistent and doing it in 5.3.3 after three versions of them working in namespaces is an iffy decision, but it's not completely insane.
|
# ? Sep 19, 2012 17:39 |
|
Suspicious Dish posted:But the only way you can evaluate macro arguments is by making them expand to other macros. And even then, you can't do any computation with that, only concatenation. Not exactly. One problem is you're trying to directly recurse, which you can't do. You need to emulate your recursion by calling a different macro. You make it reusable by having it take the name of a user-defined macro that is invoked during recursion. From that, you can create a lot of higher-level constructs without them needing redundancy themselves. You're also trying to do increment in a very complicated manner -- you shouldn't need that whole tallying thing. And to avoid giving the wrong impression, I noticed you refered to it as my fold implementation -- while I'd love to be able to take credit for Boost.Preprocessor, I am not its creator. Pilsner posted:Can someone explain the point of all those hoops and hacks with the pre-processor in C? I can't see it bringing anything but a horror of entangled dependancies and messy code, and I can't recall ever missing the feature in C#. Is there anything with macros you can't just write properly in normal code? Lots of reduced redundancy and the ability to emulate language features. Prior to the introduction of variadic templates into C++, as was pointed out, they were simulated with redundant declarations and/or template specializations up to a given maximum. You'd either do this by hand, which takes time, is error prone, and difficult to maintain, or you'd use the preprocessor. With the preprocessor, you can eliminate the written redundancy. Without something like the C preprocessor, in order to experiment with the feature, you'd have to either use some external preprocessor, therefore complicating your build process, or you'd need to modify your compiler. If you're looking for uses in C# that aren't necessarily there to just reduce redundancy, it could allow you to do compile-time computations that result in types, or do a lot of the things that we use templates or the preprocessor for in C++. It could also allow you to make embedded domain specific languages. If you really want an advanced use of the preprocessor, last year I gave a talk on a library I developed for emulating concepts in C++ without direct language support (slides are here). If you want to skip to the start of the preprocessor stuff, go to about 13:40, which is slide 10. It starts out sort of slow, but it picks up. Eventually you will see very complicated macro invocations that underneath the hood convert the input to an internal syntax tree which I then make passes over to generate a series of complicated template metafunctions (not shown, only talked about). Simple macro invocations internally end up generating tens of thousands to hundreds of thousands of characters, none of which the user ever needs to see. Edit: The talk is a little out of date. I now support variadic concepts, have automatic preprocessing of concepts via Boost.Wave (including #line directive generation) that is usable via a command line argument and that reduces compile times by more than 50%. It all compiles in both clang and in gcc. All of the proposed C++0x concepts are implemented to the extent that they can be, though some aren't able to pass all tests yet as certain features aren't fully implemented. I never ended up putting the library on the sandbox as I got caught up with other work/burnt out from all of the preprocessing stuff, but recently I've gone back to it so I'll probably put it up soon. It's over 26,000 lines of code if you do not include any of the tests. The vast majority of that code is the definition and use of preprocessor macros. That Turkey Story fucked around with this message at 21:26 on Sep 19, 2012 |
# ? Sep 19, 2012 18:41 |
|
How much would m4 buy you over cpp?
|
# ? Sep 19, 2012 19:31 |
|
That Turkey Story posted:Not exactly. One problem is you're trying to directly recurse, which you can't do. You need to emulate your recursion by calling a different macro. You make it reusable by having it take the name of a user-defined macro that is invoked during recursion. From that, you can create a lot of higher-level constructs without them needing redundancy themselves. You're also trying to do increment in a very complicated manner -- you shouldn't need that whole tallying thing. How else can you do increment?
|
# ? Sep 19, 2012 20:52 |
|
Otto Skorzeny posted:How much would m4 buy you over cpp? Suspicious Dish posted:How else can you do increment? #define INCREMENT( x ) INCREMENT ## x #define INCREMENT0 1 #define INCREMENT1 2 #define INCREMENT2 3 #define INCREMENT3 4 #define INCREMENT4 5 #define INCREMENT5 6 #define INCREMENT6 7 #define INCREMENT7 8 #define INCREMENT8 9 #define INCREMENT9 10 #define INCREMENT10 11 //etc. up to some limit That Turkey Story fucked around with this message at 21:21 on Sep 19, 2012 |
# ? Sep 19, 2012 21:08 |
|
A lookup table for Peano arithmetic??? This is your metaprogramming solution?
|
# ? Sep 19, 2012 21:35 |
|
Suspicious Dish posted:A lookup table for Peano arithmetic??? Yes. Such is the limitation of the preprocessor. The good thing is, you don't ever actually write that because high-level libraries exist that do it. Just #include <boost/preprocessor/arithmetic/inc.hpp> and use BOOST_PP_INC.
|
# ? Sep 19, 2012 21:39 |
|
Is there a way I can revoke your rights to the C preprocessor? Something tells me you should not be using it.
|
# ? Sep 19, 2012 21:51 |
|
loving C++...code:
|
# ? Sep 19, 2012 21:53 |
|
I thought NULL was defined as a size_t, which makes its size at least that of a pointer? Also, you should probably stick a __attribute__((__sentinel__)) on that.
|
# ? Sep 19, 2012 21:55 |
|
Why aren't you using nullptr?
|
# ? Sep 19, 2012 21:58 |
|
Suspicious Dish posted:Is there a way I can revoke your rights to the C preprocessor? Something tells me you should not be using it. We use whatever tools are available to accomplish the task at hand. It's not our fault if the tools aren't very powerful. shrughes posted:loving C++... The fact that NULL exists is just legacy from C. In C++, NULL's definition is implementation-defined. It might be an int, or it might not be. It can even be defined as nullptr if your compiler supports it. If you're in C++ just avoid NULL if you can, along with c-style variadic functions.
|
# ? Sep 19, 2012 22:04 |
|
Suspicious Dish posted:I do think that C needs something that enables metaprogramming a bit more than its current processor, but I'm not sure what that should entail. I'm surprised we got this far in the discussion without someone using php to preprocess C code.
|
# ? Sep 19, 2012 22:09 |
|
Suspicious Dish posted:I thought NULL was defined as a size_t, which makes its size at least that of a pointer? Also, you should probably stick a __attribute__((__sentinel__)) on that. 0 is promoted to int when passed to a variadic function. C doesn't have this problem because NULL is ((void*)0), but you can't do that in C++ because void* doesn't silently convert to any pointer type.
|
# ? Sep 19, 2012 22:16 |
|
shrughes posted:NULL is 0, so it gets passed in as an 32-bit int, so if you try to read a pointer off the arg list you can get garbage in the upper 32 bits (or undefined behavior in general, I guess). This is why NULL is not defined to be 0 on sane platforms — it's 0L or some other target-specific thing that's the size of a pointer. ETA: But yes, you should use the sentinel attribute. Clang, at least, will warn you about using a null-pointer constant of the wrong size when you do this. rjmccall fucked around with this message at 22:23 on Sep 19, 2012 |
# ? Sep 19, 2012 22:20 |
|
Preprocessor One of the projects I'm working on is a shim for an API containing hundreds of functions which need to be intercepted. Every function needs to be individually listed in code every time they are declared, initialized and deleted, so it looks something like: code:
code:
Then, we can change the definitions of the MACRO_ macros before #including this file, and then #undef them all afterwards, so the actual code looks more like this: code:
The code for generating those Functor<> definitions is also preprocessor heavy. C++11 isn't available to us yet so we can't use variadic templates.
|
# ? Sep 19, 2012 22:29 |
|
That Turkey Story posted:If you're in C++ just avoid NULL if you can, along with c-style variadic functions. What's the best alternative to c-style variadic functions if you don't have variadic templates?
|
# ? Sep 19, 2012 22:31 |
|
GrumpyDoctor posted:What's the best alternative to c-style variadic functions if you don't have variadic templates? If you're just dealing with built-in types or you need c compatibility or you need a single function, then go ahead and use them if you don't mind it and are aware of the pitfalls. If you're willing to use the preprocessor, you can use BOOST_PP_REPEAT (or include recursion) along with BOOST_PP_ENUM_BINARY_PARAMS to emulate variadic templates without much trouble.
|
# ? Sep 19, 2012 22:41 |
|
That Turkey Story posted:We use whatever tools are available to accomplish the task at hand. It's not our fault if the tools aren't very powerful. ( In response to the "your" thing from earlier, that was meant to be a collective "your", meaning the boost team. Same goes for this post as well. ) It's not your fault if the tools aren't very powerful, but it is your fault for recognizing that the tools aren't very powerful, and building systems anyway, realizing that you might be using the wrong tool for the wrong job. pseudorandom name posted:0 is promoted to int when passed to a variadic function. C doesn't have this problem because NULL is ((void*)0), but you can't do that in C++ because void* doesn't silently convert to any pointer type. Aha, thanks for the explanation.
|
# ? Sep 19, 2012 23:05 |
|
Suspicious Dish posted:It's not your fault if the tools aren't very powerful, but it is your fault for recognizing that the tools aren't very powerful, and building systems anyway, realizing that you might be using the wrong tool for the wrong job. It is the only tool for the right job -- there is no other choice within the bounds of the language. You either do something like this, or you do something like require an additional preprocessing phase before compiling your project, which creates more problems than it's worth, especially if you want a generic solution. On the other hand, when you have a tool like Boost.Preprocessor, you get a very easy-to-use solution that only requires having the necessary headers and the C or C++ compiler that you're already using. That's it, you don't have to complicate your build process, you don't have to worry about generated files being out of sync, etc. If you're not a library developer and you don't do a lot of preprocessor metaprogramming, you might not grasp just how important this is, but it is. If you're looking for a "better" solution, it's to improve the preprocessor and get the changes into the C++ standard. As was mentioned, something like m4 would make things a lot easier, but that's not a luxury we have in the realm of standard C++ development.
|
# ? Sep 19, 2012 23:29 |
|
Dicky B posted:Utterly horrible, but I'm thankful this system is in place since I can just add new functions in one place and they get automatically plugged in for me. Is there a better way of doing this? You should have functions.inc undefine the macros implicitly unless there's really a good reason that you might frequenty #include multiple files under the same set of macros. You could also avoid some of the metaprogramming (e.g. in the destructor) using smart pointers. Otherwise I feel this is pretty respectable.
|
# ? Sep 19, 2012 23:41 |
|
Another cool library of cpp hilarity/utility is P99.
|
# ? Sep 19, 2012 23:58 |
|
Preprocessing with something better than CPP is relatively straightforward (although not trivial to do entirely correctly) if you're writing an application and only care about a single platform, but once you start trying to make it portable it turns into a nightmare, and if your library requires that I modify my build system beyond adding stuff to include paths or adding more libraries to link against I'm going to hate you forever. CPP also has the advantage that any decent editor supports it to at least some extent, while custom solutions will generally break IDEs and cause issues with syntax highlighting.
|
# ? Sep 20, 2012 00:00 |
|
I did this: api.h: code:
code:
code:
|
# ? Sep 20, 2012 00:12 |
|
Plorkyeran posted:Preprocessing with something better than CPP is relatively straightforward (although not trivial to do entirely correctly) if you're writing an application and only care about a single platform, but once you start trying to make it portable it turns into a nightmare, and if your library requires that I modify my build system beyond adding stuff to include paths or adding more libraries to link against I'm going to hate you forever. Exactly, and rightfully so. If you're trying to write code that's easy to use on many projects, especially for something like boost, the only thing you're doing by introducing some artificial preprocessing step is making it unlikely that your code will be used. No one wants to bend over backwards to be able to use your code. Even the fact that most of boost is header-only helps it a lot -- just add the include directory and you're good to go for most things. I'm going to go on a rant for a second just because. A lot of people look at projects like boost and, before looking at the implementation, say "wow, this is some incredible stuff." Then, when they look at the implementation they throw a fit because in order to do that amazing stuff, you need to write some scary code, frequently using the preprocessor and/or templates in ways that the average programmer does not. Then all of a sudden there is a backlash of "this is horrible and complicated!" whereas the user would likely just be on their merry way had they never looked at the source. The fact is that the code has to be implemented in that manner otherwise you wouldn't be able to get that functionality or interface or efficiency or portability. You should be grateful that someone else wrote that code, that it's officially tested on dozens of systems (not to mention all of the programmers using the code), and that it's simple to pull into a project. It's why projects such as boost are so invaluable. The unfortunate conclusion that some people jump to after looking at the code is "those boosters shouldn't be writing code like this because it looks scary." What they really should be saying is "the language should support this functionality directly in some way so that programmers don't have to write scary code to do it." In fact, that's why a lot of C++11 comes from or was influenced by boost -- both on the library side and on the core language side. Variadic templates exist because it was clear that such functionality is extremely useful, as evidenced by the numerous boost libraries that had to simulate such functionality via the preprocessor. Templates such as std::tuple were just as useful prior to the language having variadic templates, back when they were only emulated in libraries such as boost. Yeah, it was messy to program, but the idea was just as powerful back then as it is now and claiming that templates such as those shouldn't have existed simply because they were scary to write is foolish. It sucks that some code is scary, but sometimes code just has to be scary due to other limitations.
|
# ? Sep 21, 2012 00:22 |
|
code:
|
# ? Sep 21, 2012 03:07 |
|
That Turkey Story posted:I'm going to go on a rant for a second just because. A lot of people look at projects like boost and, before looking at the implementation, say "wow, this is some incredible stuff." Then, when they look at the implementation they throw a fit because in order to do that amazing stuff, you need to write some scary code, frequently using the preprocessor and/or templates in ways that the average programmer does not. Then all of a sudden there is a backlash of "this is horrible and complicated!" whereas the user would likely just be on their merry way had they never looked at the source. The fact is that the code has to be implemented in that manner otherwise you wouldn't be able to get that functionality or interface or efficiency or portability. You should be grateful that someone else wrote that code, that it's officially tested on dozens of systems (not to mention all of the programmers using the code), and that it's simple to pull into a project. It's why projects such as boost are so invaluable. What if something goes wrong? What if I'm using boost::preprocessor, and suddenly, I encounter an issue. Trying to figure out what's wrong, I press "continue" on my debugger, and I get this: http://www.boost.org/doc/libs/1_49_0/boost/preprocessor/detail/auto_rec.hpp
|
# ? Sep 21, 2012 03:20 |
|
Suspicious Dish posted:What if something goes wrong? What if I'm using boost::preprocessor, and suddenly, I encounter an issue. Trying to figure out what's wrong, I press "continue" on my debugger, and I get this: Did you actually read the part of that post after the bit you quoted?
|
# ? Sep 21, 2012 03:35 |
|
Jabor posted:Did you actually read the part of that post after the bit you quoted? Yes.
|
# ? Sep 21, 2012 04:27 |
|
Suspicious Dish posted:What if something goes wrong? What if I'm using boost::preprocessor, and suddenly, I encounter an issue. Trying to figure out what's wrong, I press "continue" on my debugger, and I get this: First off, if you press continue in your debugger, you're never going to see that, and as someone who works a whole ton with preprocessor metaprogramming and who has developed entire libraries built around preprocessor metaprogramming using Boost.Preprocessor, I don't think I've ever had a problem with it period (again, this isn't that surprising given the amount of testing that goes on and the amount of libraries that depend on it). If I did have a problem and somehow couldn't figure it out, there is an enormous community to look to for questions and they are always willing to help you out with whatever problems you may have in a very short period of time and would likely fix the problem for you. Further, the amount of time and debugging it saves you if you hand-rolled something instead can't be ignored either, though it often is. Anyway, again, if you are looking to do preprocessor metaprogramming, what are your other options? I've already explained why separate preprocessors are usually not a great choice. Boost.Preprocessor, on the other hand just works with no complications, is fast, and extremely portable. If your alternative is "don't use preprocessor metaprogramming" then you've either never encountered a problem that would benefit from its use or you simply never thought to consider it as option -- either way, I don't see how you can consider yourself qualified to make a sound judgment on the library's implementation or its usefulness. There often is no better choice, and if you don't like how such libraries have to be implemented, all I can say is get active in the C or C++ community and try to improve the preprocessor for the next standard.
|
# ? Sep 21, 2012 05:45 |
|
I was taking an interview for a potential new company, mobile games stuff, nothing too complicated. I've been a lead/senior engineer on games for some time now and already have a year of experience at a company in S. Korea where I'm living. After some already excessive hoop jumping, 3 spoken interviews, a 2 hour written test and some very personal stuff that I found kind of offensive, they offered me the job and gave me a starting date. Oh, only except one more test which they gave the day after. "You have 4 days to implement a Minesweeper clone, supply the source by Sunday evening". Ok fine, I have to be with family the first two of those days and help my friend move apartment on the other two, I really don't understand why they can't just accept a code sample like everybody else, this isn't exactly an important or high paying position, but whatever, they're the boss. The only condition I was given is that wanted to see if my code could be used for efficient team working. The company is current achieving 0% code reuse between games so that was brought up as something I'd likely be helping out with. As they're a mobile company I put together something cross platform, portable and suitable for both desktop and mobile. I used my own simple engine for duplicating content between Flash and HTML5, pulled the components I needed for the game, made minimal changes to separate game logic from presentation within them, plugged things in and sent it off on the Sunday evening to meet the deadline. After nothing for a week I get called back to the office yet again. "Hi, your written test scores were excellent, but the project you provided was very bad." Oh, could you explain why? I thought I met the re-use requirement you laid out in the interview quite well. I hardly used any original code at all. "We don't want to discuss this in front of anybody, we will email you later." Several days later the email arrives, it's very aggressively written. "Your code for the game logic is bad, you should have done x, y and z". I made the source of that code very clear in the file headers, it wasn't written by me, you wanted to see examples of how code reuse could be leveraged so that's what I did. I used existing, well tested code, and if I redid the whole thing I would be re-writing a solved problem making it a poor test of code re-use and possibly introducing bugs. They hadn't criticized any other of the extensive library code I had used, only that one. "Also we decided you should be combining the 'button' classes (marked as view logic) in with the game rules class (marked as a model), this is undoubtedly wrong so we deducted a lot of points for it" Well, with respect, I can't agree that combining presentation and application logic is a good idea, I don't think I can be doing things like that. This seemed to particularly enrage them and they accused me of being inflexible. Also everything viewable was part of a composite scene/display graph pattern, which they didn't seem to understand at all, and seemed to have deducted points for also. "You should be using a controller class, to separate view and model logic. The Class is the primary tool for communicating between programmers. We again deducted points." After suggesting that I should be mixing everything together? Also I think that's a very strict object oriented view, I did something more functional with respect to the language and closer to the MVVM pattern, I'd agree if I were writing Java code for example. At this point I was happy I didn't go with my original plan to implement the game in Haskell. I had already asked the intermediary in this conversation to check that I was coming across politely, it might sound belligerent but I was being asked to improve code reuse between teams and would need some authority to be able to do that. Although if they wanted to see examples of classes I had written then there were plenty of them in the project, I offered that this point to rewrite the offending game logic classes using my style and coding standards although with respect again, it's kind if against my philosophy to do so. This unreasonably enraged the guy and he wrote a lot of words about how he didn't care who my code had been tested by, I started to write back that it's not of concern to him if my code has been tested and reviewed or not, it's of concern to me for if I supply a working product or not. I deleted that and decided not to reply anymore, which they beat me to by telling me I wouldn't be joining the company any more. For anybody wondering why I went to all this effort, hard work and dedication are often valued over everything else in Korean companies and education, so it's something usually important to show, there also aren't a lot of good opportunities. I don't claim that I did everything right here, just I think there's room for subjective discussion beyond, we deducted points because X, you're wrong. I got a nice code sample out of it at least.
|
# ? Sep 21, 2012 05:54 |
|
Sounds like you dodged a bullet, they did their best not to hire you and they sound completely loving dysfunctional.
|
# ? Sep 21, 2012 07:54 |
|
Definitely dodged a bullet. The red flag to me immediately was that this was regarding mobile games, which has become the pinnacle of lovely employers/lovely workplaces lately. The combination of people expecting everything to be done as fast as possible at any (edit; non-monetary) expense, and the tendency to favor really bad design if it has worked in the past (albeit poorly) makes for a really, really lovely time. Their inflexibility on how they think you should be coding, despite it conflicting with their re-use requirement is a good example of how bad some of these places can be; they get feedback from developers about re-use ("why isn't this game finished already" "it's because we can't re-use any code") and have absolutely no clue about what in their process is hindering re-use in the first place. Without a doubt the guy you spoke to was the "lead" developer, and is a complete fuckass that everyone in the company hates because he's constantly pushing his awfulness onto everyone else (everybody knows someone like this, and hopes they never get into a position of power). The Gripper fucked around with this message at 08:06 on Sep 21, 2012 |
# ? Sep 21, 2012 08:01 |
|
The best name I've ever given a thing is:code:
It hasn't exposed any HTML injection vulnerabilities for a while, but now it seems that someone has hand-rolled a JSON encoder.
|
# ? Sep 21, 2012 09:51 |
|
The Gripper posted:Definitely dodged a bullet. The red flag to me immediately was that this was regarding mobile games, which has become the pinnacle of lovely employers/lovely workplaces lately. The combination of people expecting everything to be done as fast as possible at any (edit; non-monetary) expense, and the tendency to favor really bad design if it has worked in the past (albeit poorly) makes for a really, really lovely time. I was kind of spoiled at my last mobile games job where a lot of the top people are also big open source contributors, I got schooled on coding but they did belong in a business decisions horrors thread. I choose mobile games a lot because it's easier for me to bring a lot to the table. The sad thing is this company could easily achieve huge code reuse because the games are all basically the same genre, I'm sure using data driven methods they could be looking to cut dev times from 8 months per a game to 8 weeks.
|
# ? Sep 21, 2012 11:07 |
|
That Turkey Story posted:
Another good example is the code for the std::vector class itself, which gets my vote for the most difficult to read widely-used class ever.
|
# ? Sep 21, 2012 12:54 |
|
plashy posted:some very personal stuff that I found kind of offensive, This is the part where I would have walked out. If they can't respect you before they hire you, you can bet they won't respect you while working there.
|
# ? Sep 21, 2012 14:31 |
|
|
# ? May 17, 2024 01:33 |
|
Wheany posted:The best name I've ever given a thing is:
|
# ? Sep 21, 2012 14:47 |