8 ms·
Every time there's something that comes up for C++ I get excited, I've always wanted to use the language, but it's like tap dancing in a mine field. C++ needs
by codebeaker 10y ago
Every time there's something that comes up for C++ I get excited, I've always wanted to use the language, but it's like tap dancing in a mine field.
C++ needs a linter that rejects code that doesn't meet a certain standard ala Rubocop.
- pjmlp 10y agoMost C++ compilers have them, the problem is the macho coders that think that know best. The same that micro-optimize every single line of code they write without ever running the code through a profiler.
- 0xFFC 10y agoMy rule of thumb : never optimize your code, instead optimize your algorithm as much as you can. After you finish, you can profile your code to see where you made mistake.
- hellofunk 10y agoPerfect advice. Most bottlenecks are not because of coding details, but algorithmic or architectural concerns.
- kgabis 10y agoIt's hard to optimize your code if you made bad decisions about memory layout of your data structures in the past.
- paulddraper 10y agoAlgorithm optimizations can be far less readable than other kinds. Matrix multiplication is super simple. Strassen is more complicated. Coppersmith–Winograd is brain bending (besides being slower on actual data and hardware). The rule of thumb is: you have a complexity budget and a performance budget. Know what they should be, and choose economically.
- byuu 10y ago> Most C++ compilers have them, the problem is the macho coders that think that know best. If you mean the warnings, it's because they're way over the top. switch(enabled) > warning: switch on bool switch(static_cast<int>(enabled)) Sigh. Now I know, "why would you ever switch on a bool?! It's only two possible states!" Because it was in an ARM CPU emulator that decoded three to five fields per instruction, most of which were multiple bits long, but a few were just one bit. It gave a structured, consistent look to the code for each field to be implemented with a switch. That's just one example, though. My current list of, "are you kidding me?" warning disables for Clang are: #pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic ignored "-Wempty-body" #pragma clang diagnostic ignored "-Wparentheses" #pragma clang diagnostic ignored "-Wreturn-type" #pragma clang diagnostic ignored "-Wswitch" #pragma clang diagnostic ignored "-Wswitch-bool" #pragma clang diagnostic ignored "-Wtautological-compare" #pragma clang diagnostic ignored "-Wabsolute-value" This was all for perfectly legal, unambiguous code. Anything even remotely suspicious I'd fix. You probably still think I'm a macho coder anyway, but I'm honestly not. I'm just rather obsessive about consistency and simplicity in my code. I would really not enjoy working on a codebase that forced me to use -Wall -Wextra -Werr.
- twoodfin 10y agoWhy disable tautological-compare? Of all the pickier warnings over the years, anecdotally I'd say it's been one that's caught an outsized number of actual bugs. >= 0 on an unsigned value is the classic one.
- byuu 10y agoIt triggers a lot in generic code (eg templates), where it's not so obvious the result is going to be tautalogical until you instantiate the template. Another time I've used it is just pure aesthetics: if(addr >= 0x0000 && addr <= 0x7fff) return ram.read(addr); if(addr >= 0x8000 && addr <= 0xbfff) return cpu.read(addr); if(addr >= 0xc000 && addr <= 0xffff) return apu.read(addr); Looks nicer than: if(addr <= 0x7fff) return ram.read(addr); if(addr >= 0x8000 && addr <= 0xbfff) return cpu.read(addr); if(addr >= 0xc000 && addr <= 0xffff) return apu.read(addr); And the compiler will delete the unnecessary comparison anyway, so there's no great reason to warn about it. And now imagine you want to make it even nicer, so you add between(addr, lo, hi) as a macro: (note: not a real example -- I wouldn't do this for this case, just for demonstrative purposes.) if(between(addr, 0x0000, 0x7fff)) ...; if(between(addr, 0x8000, 0xbfff)) ...; if(between(addr, 0xc000, 0xffff)) ...; Now you have the generic code triggering the warnings again.
- bstamour 10y agoC++ has that. Check out clang_tidy [1]. EDIT: In particular, the clang tidy linter has a way of checking your code against the C++ core guidelines [2], which is a set of modern best practices for the language. [1]. http://clang.llvm.org/extra/clang-tidy/ http://clang.llvm.org/extra/clang-tidy/ [2]. https://github.com/isocpp/CppCoreGuidelines https://github.com/isocpp/CppCoreGuidelines
- progman 10y agoYeah, C++ has that. Other languages - Ada and Rust for instance - don't need that. If you are concerned about code safety then C++ is not a good choice.
- bstamour 10y agoYeah, I kind of agree that C++, when used badly, can result in some serious mess-ups in the safety department. But for better or worse the language is here to stay (at least for the foreseeable future) so it's good that these guidelines and tools exist.
- dahart 10y ago?? Compilers do reject code that doesn't meet a certain standard. C++ does come with a "linter". You might want to check out what -Wall does in gcc & clang. I've never met a linter I liked more than a real compiler, not even close. Linters for scripting languages only exist because the scripting languages aren't compiled, and they are only lightweight second rate optional type checkers. Linters' attraction and usefulness is that you aren't required to use them, so you can iterate quickly and run code without having to wait for the compiler every single time you save your file. Linters are not better at keeping you within good style and safety bounds, generally speaking.
- Manishearth 10y ago> Compilers do reject code that doesn't meet a certain standard. Yes, a bare minimum standard, which must be backwards compatible. What a compiler enforces is not best practice, it is bare minimum. Something enforcing best practice has to be allowed to be backwards incompatible, since newer better ways of doing things will always come up (that's how languages evolve), and you want to discourage the older stuff. "I've never met a linter I liked more than a real compiler" -- it's not an either or situation, use a linter on top of the compiler.
- dahart 10y ago> What a compiler enforces is not best practice, it is bare minimum. -Wall gives you a lot more than bare minimum. But, you can't really call it bare minimum when you compare compilers to linters in general. If a compiler enforces bare minimum, then a linter enforces less than bare minimum. Linters in general do not detect type errors that compilers catch and that prevent the program from running. A compiler is a bigger, better safety net than a linter. I have ~25 years experience with many linters and many compilers, and my opinion is that compilers provide more security than linters, on the whole. When I can, I try to use a real compiler for production use of scripting languages, for example Google's closure compiler in JavaScript rather than linters like eslint or jslint. > it's not an either or situation, use a linter on top of the compiler. This is true, and I agree completely, it's not an either-or situation. That's in part what I was trying to say. The compiler already does linting and it does much better static analysis, so you don't need to choose, you can just use a compiler. There are certainly higher level style analyzers, clang-tidy was mentioned already, and there are others. PEP-8, and Rubocop are in part a set of guidelines designed to prevent code mistakes and type errors precisely because the languages they represent don't come with a static type-checking compiler. Many of the linting rules and best practices only exist to prevent unsafe code that would have been prevented if there was a compiler involved, and only need preventing via style guides and linters because a compiler is not necessarily there. There are certainly best social practices that some linters enforce that many compilers don't, but for that it doesn't make any sense to avoid learning C++. The OP's comment - that he feels like C++ is a minefield without a linter - is missing the forest. It is easier to know you're writing correct C++ than it is to know you're doing correct Python, because of C++'s compiler. Unfortunately no compilers or linters are that good at preventing you from writing code that runs and then crashes.