An anti-pattern is a solution you find yourself using unintentionally that you notice is causing you pain later on down the line. The first 10 times or so you just fix the pain, you don't start noticing it until instance 20 or so. If you were to study that anti-pattern, you could figure out why it's causing you pain, and maybe even solve the pain points and turn it into a real software pattern.
If I'm doing exploratory programming that I don't expect to have to support or maintain, sure, I'll use all the power tools I can get my hands on to do cool shit with. But when I'm working on systems I don't care personally about, I want as little friction as possible between problem and solution. I don't want to have to look at a piece of code and wonder, "WTH is that doing again?" I notice myself having that reaction far more when there's metaprogramming involved than when there's not.
It's not that there's no way to use metaprogramming effectively or maintainably. It's just that I have to think that much more carefully about proper separation of concerns, how the messages are passing, what happens when there's errors, stuff I don't have to think about when I'm doing it the boring way. When something goes wrong in boring Ruby, the backtrace is all I need to figure out what's going wrong.
I've had the experience way too many times, of, over a dozen or so refactorings of a piece of metaprogramming I was too proud of to rip out, finally realizing that there was a bit of state I could have passed in a perfectly normal fashion that would have completely eliminated the need to, say, do dynamic class generation. Had I not been so hung up on my own brilliance, I could have saved myself hours of effort.
Likewise, if you find yourself reaching for manual memory management, that is, rolling your own management structures rather than using one of the countless well-tested constructs available, without really understanding why, then you're probably overlooking some library you could use that would do exactly what you want it to do and handle all the myriad edge cases had you given it some thought. I would absolutely consider manual memory management an anti-pattern unless you're working in embedded environments or demoscene, and sometimes even then. C is way too mature for you to be reinventing things.
Programmers are some of the most masochistic professionals I've ever met. They don't want to do things the easy way, easy seems to equate to stupid for them. You're not Linus Torvalds, the stakes just aren't that high. An .8kB in superfluous code loaded up in memory alongside the .2kB of the library you do need isn't going to kill you, only keep you sane. Don't make unnecessary work for yourself. Finish up early and go home and spend time with your kids.