|
Suspicious Dish posted:The preprocessor really should always insert parens for you automatically. I can't think of a single reason for it not to. code:
|
# ? Sep 18, 2012 23:52 |
|
|
# ? Jun 1, 2024 10:07 |
|
That Turkey Story posted:You mean have macros always expand to something parenthesized? That wouldn't work -- the are lots of times where you don't want the expansion to result in something that's parenthesized I.E. almost anything that doesn't result in an expression. I meant "when the preprocessor results in an expression, parenthesize it automatically".
|
# ? Sep 18, 2012 23:56 |
|
Suspicious Dish posted:I meant "when the preprocessor results in an expression, parenthesize it automatically".
|
# ? Sep 18, 2012 23:59 |
|
Suspicious Dish posted:I meant "when the preprocessor results in an expression, parenthesize it automatically". code:
|
# ? Sep 19, 2012 00:25 |
|
Gigantic Slut Man posted:
It's so contrived it won't compile!
|
# ? Sep 19, 2012 00:44 |
|
Plorkyeran posted:Determining whether or not a thing is a valid expression is way more complicated than anything the C preprocessor does. I don't think so. It already takes comments and strings into account, and certainly parses a lot of C's existing structure. Determining whether the macro expansion will result in an expression isn't that hard, I don't think.
|
# ? Sep 19, 2012 00:46 |
|
Gigantic Slut Man posted:
IIRC you'd need ## to do that, not just a define
|
# ? Sep 19, 2012 00:47 |
|
Suspicious Dish posted:It's so contrived it won't compile! durr. Brain fart. Whatever, #DEFINE TWOPLUSTWO 2 + 2 a = TWOPLUSTWO * 5
|
# ? Sep 19, 2012 00:53 |
|
Suspicious Dish posted:I don't think so. It already takes comments and strings into account, and certainly parses a lot of C's existing structure. Determining whether the macro expansion will result in an expression isn't that hard, I don't think. No. If you forget parentheses, braces, or a semicolon, it is your fuckup and you should fix it. The preprocessor should do a simple job and do it well. That is C's place among the languages: To do as it is told and follow rules no simpler and no more complex than necessary. Manning up, and learning to macro is better than getting used to parentheses magic. P.S. do { /* code goes here */ } while(false) is a pretty neat trick to use for non-expression macros.
|
# ? Sep 19, 2012 00:58 |
|
Gigantic Slut Man posted:durr. Brain fart. Whatever, #DEFINE TWOPLUSTWO 2 + 2 Which by any reasonable logic should result in a = 20, not a = 12. But yeah, putting parenthesis around defines is pretty much your own responsibility.
|
# ? Sep 19, 2012 01:01 |
|
KaneTW posted:Which by any reasonable logic should result in a = 20, not a = 12. But yeah, putting parenthesis around defines is pretty much your own responsibility. No, because it's a macro language and not a programming language. It doesn't evaluate statements, that's not part of what it sets out to do. It's a contrived example that shows where something which is an expression has its meaning changed by inserting parenthesies, please do not focus on my specific example. Bunny Cuddlin fucked around with this message at 01:05 on Sep 19, 2012 |
# ? Sep 19, 2012 01:03 |
|
E: never mind, this is silly
|
# ? Sep 19, 2012 01:06 |
|
Doctor w-rw-rw- posted:Manning up, and learning to macro is better than getting used to parentheses magic. or we could get a modern compile-time shenanigans system where we don't have to teach people to place bullshit parentheses everywhere and abuse loops
|
# ? Sep 19, 2012 01:10 |
|
Gigantic Slut Man posted:durr. Brain fart. Whatever, #DEFINE TWOPLUSTWO 2 + 2 Thanks for proving my point for me. Gigantic Slut Man posted:No, because it's a macro language and not a programming language. It doesn't evaluate statements, that's not part of what it sets out to do. Who said it should? Doctor w-rw-rw- posted:No. If you forget parentheses, braces, or a semicolon, it is your fuckup and you should fix it. Fixing various syntax errors is not the goal of the preprocessor, nor do I believe it should become one. Doctor w-rw-rw- posted:The preprocessor should do a simple job and do it well. That is C's place among the languages: To do as it is told and follow rules no simpler and no more complex than necessary. The rules the preprocessor follows aren't that simple already. There's no reason we can't add a few more Doctor w-rw-rw- posted:P.S. do { /* code goes here */ } while(false) is a pretty neat trick to use for non-expression macros. The fact that that technique exists and is prevalent as it is, despite being complete nonsense, argues to me that the preprocessor deserves a bit more power and responsibility. If the do...while syntax didn't have the exact syntax it does, this trick wouldn't work. It's abusing an unintended part of the grammar not for its functionality, but for its syntax.
|
# ? Sep 19, 2012 01:11 |
|
It's hardly a thing I'd propose for literally the C preprocessor but trying to romanticise its behavior beyond it being more trouble than it'd be worth to replace it is silly.
|
# ? Sep 19, 2012 01:11 |
|
I suppose we just have differing ideas about the preprocessor: I believe it should be as simple as possible so that you can do your programming in, you know, the programming language it supports. Adding a mini-parser to the preprocessor sounds like a horrible idea to me.
|
# ? Sep 19, 2012 01:17 |
|
Vanadium posted:It's hardly a thing I'd propose for literally the C preprocessor but trying to romanticise its behavior beyond it being more trouble than it'd be worth to replace it is silly. Abusing the C preprocessor is as valid a sport as golf.
|
# ? Sep 19, 2012 01:17 |
|
Suspicious Dish posted:The rules the preprocessor follows aren't that simple already. There's no reason we can't add a few more Yeah, why not make an incompatible change to the language's semantics. Who cares if existing code won't work anymore?
|
# ? Sep 19, 2012 01:30 |
|
Gigantic Slut Man posted:I suppose we just have differing ideas about the preprocessor: I believe it should be as simple as possible so that you can do your programming in, you know, the programming language it supports. Adding a mini-parser to the preprocessor sounds like a horrible idea to me. That's a respectable idea, but the problem is that the C preprocessor isn't simple, already. 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.
|
# ? Sep 19, 2012 01:33 |
|
C provides a lexical (token-based) preprocessor. What you want is a non-lexical preprocessor, i.e. not really a preprocessor at all so much as a compile-time metaprogramming system capable of generating, suppressing, and modifying arbitrary language structures. That is possible, but it's far, far more complicated and substantially more sophisticated than what people were doing in compiled languages 35 years ago; in fact, the only significant compiled languages I know of with that ability are in the LISP family.
|
# ? Sep 19, 2012 01:47 |
|
Suspicious Dish posted:That's a respectable idea, but the problem is that the C preprocessor isn't simple, already. It's simple compared to what you want. Right now all it needs is the result of the lexxer, you want to add a parser. That's another layer of complexity entirely.
|
# ? Sep 19, 2012 03:01 |
|
Suspicious Dish posted:I don't think so. It already takes comments and strings into account, and certainly parses a lot of C's existing structure. Determining whether the macro expansion will result in an expression isn't that hard, I don't think. Those are all very trivial. The preprocessor basically has no knowledge of C++ or C for that matter. It doesn't even know what an expression is let alone how to differentiate one from other code. This is actually very complicated in C++. For a simple example: int( foo ) What is that? Is that an expression or is it a type? It depends on what foo is. If foo is a type, then int( foo ) is also a type. If foo is not a type, then that's an expression constructing an int from foo. Also, what about macros that are partial or potentially partial: #define foo -a What is that? Is that -a or is that the second part of a subtraction? There's a ton more stuff to consider other than what I've shown that make it impossible to determine whether or not the user actually wants parentheses, even in the case of expressions. 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 with you there. Right now the C preprocessor is technically Turing complete, but it's still a bitch to do complicated stuff with.
|
# ? Sep 19, 2012 06:03 |
|
That Turkey Story posted:Those are all very trivial. The preprocessor basically has no knowledge of C++ or C for that matter. It has some language semantics embedded in it, but yeah, I guess it can be done with only a lexer, transforming the token stream as it goes through. That Turkey Story posted:It doesn't even know what an expression is let alone how to differentiate one from other code. This is actually very complicated in C++. For a simple example: There's a reason I don't write C++. That Turkey Story posted:Also, what about macros that are partial or potentially partial: Yeah, I guess I didn't think of all those edge cases. That Turkey Story posted:I'm with you there. Right now the C preprocessor is technically Turing complete, but it's still a bitch to do complicated stuff with. Isn't looping sort of required to be turing complete?
|
# ? Sep 19, 2012 06:11 |
|
The standard tries to disallow recursive macros, but you can use some clever tricks to effectively allow recursion up to a fixed stack size.
|
# ? Sep 19, 2012 06:33 |
|
Jabor posted:The standard tries to disallow recursive macros, but you can use some clever tricks to effectively allow recursion up to a fixed stack size. But you can't keep state when looping, which I thought was necessary.
|
# ? Sep 19, 2012 06:47 |
|
Suspicious Dish posted:But you can't keep state when looping, which I thought was necessary. You'd be surprised what you can achieve if you
|
# ? Sep 19, 2012 06:57 |
|
Suspicious Dish posted:Isn't looping sort of required to be turing complete? code:
|
# ? Sep 19, 2012 06:59 |
|
Jabor posted:You'd be surprised what you can achieve if you I doubt I'd be.
|
# ? Sep 19, 2012 07:04 |
|
Suspicious Dish posted:But you can't keep state when looping, which I thought was necessary. Hmm? You pass along the state as macro arguments. You can emulate fold with the C preprocessor -- Boost.Preprocessor has an implementation. In fact, you can emulate all sorts of constructs up to a given limit. For instance, you can implement recursion in the more general sense than just fold, you can do while, for each, you can even emulate mutability, and more (Chaos even has lambda functions)!. Of course, most of these library-emulated constructs have limits and you "recurse" up to a given depth. You could probably argue that because of this it is not really Turing complete, but that ends up being somewhat unimportant especially since all compilers effectively have internal limits anyway. The only difference is that the limits with the C preprocessor for recursion are library-dependent as opposed to compiler dependent. In practice, that difference doesn't actually matter. That Turkey Story fucked around with this message at 07:15 on Sep 19, 2012 |
# ? Sep 19, 2012 07:12 |
|
That Turkey Story posted:Hmm? You pass along the state as macro arguments. 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. Wait a minute... C code:
I haven't looked at your crazy fold implementation. Am I anywhere near the solution?
|
# ? Sep 19, 2012 08:27 |
|
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?
|
# ? Sep 19, 2012 09:35 |
|
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? Suppose you wanted to write a function that accepted a heterogeneous sequence of parameters, did something to them, and passed it on to something else. Generics + varargs solve the problem for a homogeneous parameter list, of course, but if you want to handle heterogeneous parameters then you're stuck writing a separate function for each different number of parameters, all of which are close to identical. This is where metaprogramming (of which heavy macro use is an example) comes in handy. It's typically not especially useful for application development, but it's really good for building highly-reusable libraries.
|
# ? Sep 19, 2012 09:52 |
|
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? Of course not, whatever you write in macro ends up as code, so you could do with the expansion directly. It's easy to fabricate horror stories about pre-processor macros, which only emphasize the fact that care should be taken when writing macros. There are plenty of examples of macro packages that help write easier to read and maintain code. And that's where the pre-processor is useful. I was really fond of windowsx.h, in the ancient times when I was writing win16/32 code in C. That was a neat macro package in an ocean of messy header files.
|
# ? Sep 19, 2012 09:55 |
|
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? Hopefully this code will never be used in production. It's just a fun puzzle for me: do arithmetic and also repetition with only concatenation.
|
# ? Sep 19, 2012 10:00 |
|
A good example of clever macro use I found was in the Teeworlds source. Here, all game variables are defined in a header file, using some macro functions: C code:
One could argue if there are better ways of doing it, but it works and provides a convenient location to easily define new variables with a pretty clean syntax, so I'd call it a pretty good use of macros.
|
# ? Sep 19, 2012 10:08 |
|
Known as X-Macros.
|
# ? Sep 19, 2012 10:11 |
|
Jabor posted:Suppose you wanted to write a function that accepted a heterogeneous sequence of parameters, did something to them, and passed it on to something else.
|
# ? Sep 19, 2012 12:58 |
|
Jabor posted:Generics + varargs solve the problem for a homogeneous parameter list, of course, but if you want to handle heterogeneous parameters then you're stuck writing a separate function for each different number of parameters, all of which are close to identical. Er whut? code:
|
# ? Sep 19, 2012 14:06 |
|
Zombywuf posted:Er whut? "What's the point of metaprogramming? See, you can do the exact same thing by using this other metaprogramming feature!"
|
# ? Sep 19, 2012 15:29 |
|
|
# ? Jun 1, 2024 10:07 |
|
Realtalk, Pilsner mentioned C# so I picked something that C#'s existing facilities don't handle cleanly. Yes variadic templates handle that specific example pretty well.
|
# ? Sep 19, 2012 15:34 |