Posts

Showing posts from July, 2015

VS 2015 projects: "One or more errors occurred"

Image
For the most part, I find that Visual Studio 2015 is awesome. However, it did ship with kinks that need to be worked out. Not least, it has crashed on me from time to time, while working on a large solution.

I recently experienced a problem where I couldn't open Visual C++ projects (.vcxproj) after I copied them to another location. When trying to open the projects, VS 2015 would give me nothing more than this "extremely useful" error:


That is some talent, right there. That must have taken a lot of work to get this right.

After trying various things, and having researched this without success for a few hours, I finally got the idea to try opening the projects in Visual Studio 2013, instead.

Behold: VS 2013 actually displayed a useful error, which informed me that my projects had Import dependencies that I forgot to move.

So, yeah. If VS 2015 helpfully tells you that "one or more errors occurred" — try VS 2013.

Algorithm for selective archival or aggregation of records

Given the absurdity of the US patent system, it comes to mind that I should publish all technical ideas, no matter how inane, when I think of them — simply to provide a prior art reference, in case anyone claims that idea in a future patent.

The ideas I publish are arrived at independently, and based on publicly available information. This does not mean that existing and currently "valid" patents don't exist that cover parts of my ideas. It does, however, mean that such patents are obvious, and that the patent system is legalized enabling of extortion.

Without further ado, here's an idea for how to archive old log files to:
maintain required storage under a manageable threshold;store the latest data, as well as older data in the event of undetected corruption;avoid predictability to an attacker who might rely on a particular pattern of deletion.We assume that log files are being archived in regular periods. This period may be an hour, a day, a week, or whatever works …

Exceptions in destructors and Visual Studio 2015

If you're migrating code to Visual Studio 2015, you may have run into the following warning:
warning C4297: 'A::~A': function assumed not to throw an exception but does note: destructor or deallocator has a (possibly implicit) non-throwing exception specificationYou may not have seen this warning with GCC or Clang, so you may think VS 2015 is just bothering you. Wrong! GCC should be warning you even more so than Visual Studio (I'll explain why), but it does not.

You may also think that throwing an exception from a destructor in C++ is inherently undefined behavior. Wrong! Throwing an exception from a destructor in C++ is extremely well defined.

In C++03, throwing an exception from a destructor works as follows:
If there is no exception in flight, it means the destructor is being called through forward progress. In this case an exception in the destructor causes the beginning of unwinding — backward progress — just as if the exception was thrown anywhere else. The obje…

The main asset of the US is its value system

And what the US is doing, with respect to spying and whistleblowing, compromises it.

I was following a thread discussing the benefits of having the NSA and CIA, when they didn't even stop the Chattanooga shooter — who shot four marines, but not before writing about Islam on a public blog. Discussion evolved to that maybe the benefits are economic. That maybe these agencies don't stop most bad things from happening, but the US reaps benefits from stealing secrets from other countries.

I find it disturbing to talk about stealing as something acceptable just because it's done between countries instead of between people.

How would stealing from other countries benefit the people of the US? To make use of what you've stolen, you have to give it to some company. Does that really help the average American, or just tycoons with ties to spooks?

To the extent that the US is doing things right, it has been, and should continue to be, the country to be stolen from; not a country t…

Whistleblowing policy proposal

We face the problem of what to do with people like Assange, Manning, and Snowden, to encourage justified whistleblowing, and yet for secrecy to still be available to projects that really need it. (And let's be mindful here that many projects that believe they need secrecy, really do not.)

I propose that any act of whistleblowing done demonstrably out of idealism, and in good faith, should be protected and given immunity for, one time in a person's life. People who have used this card should lose their career, and no longer be employable in this or any other career that requires clearance. But they should be able blow the whistle one time.

Everyone currently employed in careers that require clearance would have to have this card still available to them — to avoid someone stacking a team full of people who've already been made to spend their card on purpose.

Everyone in powerful positions would then expect that everyone around them has this one-time get-out-of-jail-free card…

SFTP and OpenSSH's "do as we please"

It bugs me that OpenSSH pull all the same crap that Microsoft was vilified for years ago.

They sabotaged the SFTP standardization process. They are "embracing and extending" as they please, and leveraging their market share in unilateral decisions that ignore the needs of other implementations.

Their quality is also not as awesome as their contributors sometimes seem to believe. They seem to be doing better recently — but historically, they have a nice long list of security issues. This is not to mention bugs that are just bugs, and require workarounds. Just the latest of these is an SFTP data stream corruption if there are commands producing output in .bashrc; because you know, it makes sense for OpenSSH to launch their SFTP subsystem in a way that runs .bashrc; and it makes sense to send garbage output from .bashrc like it was part of the SFTP session to the client. ;)

So that's one workaround we're adding in our next Bitvise SSH Client version.

But this is not to …

Aggregated exceptions: Proposal summary

Based on my previous post about errors in destructors and aggregated exceptions, I first made a Reddit thread, and then a proposal in the ISO C++ Future Proposals group. Based on feedback I've received, the proposal has evolved, and would benefit from a page where its current state is published.

I summarize the proposal's state. I will update this if I get further feedback prompting change.

JustificationThere is a problem which I believe is limiting C++ in its potential for powerful expression. The problem is the single-exception policy, and its direct consequence: the marginalization of destructors, exemplified in recent years by how they're now marked by default noexcept.

I believe this problem is currently viewed incorrectly by many, and I wish to propose a solution. The solution is aggregated exceptions. I contend these are conceptually simple; resolve the Gordian Knot of destructor exceptions; are backward compatible, and straightforward to implement. :-)

There is a wi…

Errors in destructors: C++ and the case for aggregate exceptions

See update in my following post:
Aggregated exceptions: Proposal summary


In a recent post, I suggested that when a destructor detects a cleanup error, throwing an exception is an acceptable way to report it. I argued that reporting problems is always preferable to ignoring them, so if a destructor does detect a problem, throwing is better than doing nothing. In the worst case, it will cause a whole program abort, which in unexpected circumstances is yet better than no reporting.

It turns out that, with C++11, the language committee took the opposite stance on the issue. Quite simply, all destructors are now declared noexcept(true) unless you go to the trouble of declaring them noexcept(false) - in which case, you are on your own, and the STL doesn't like you.

In Visual C++ 2010 and 2013, support for noexcept is not implemented, so behavior remains as in C++03. However, if you compile the following with g++ -std=gnu++11:

struct A {~A(){throw"all good";}};intmain(){try{ A a;…

Code as concise expression of thought

At risk of coming across like Jaden Smith, let me wax philosophical about programming.

All code is thought, and development is unfolding of a thought process using the computer as external infrastructure in which to hang thoughts that don't all concurrently fit in your head. Therefore, the current state of your code reflects your current understanding of the problem you're solving. This understanding has to improve over time, but it usually does not radically change. Being good at development means being good at expressing your current state of mind in code; writing it so it's a true reflection of your thinking, rather than a muddled one.

Therefore, when you write code in a way that it's in harmony with your thought, changing your thought in a small way will produce a similarly small change in code. If changing your thought in a minor way causes large changes in code, it means you're expressing yourself poorly.

Your production code should assert

If you have C or C++ experience, you're familiar with asserts. Here's just one example use case in a Visual Studio 2013 include file:

bool _HasCapturedContext()const{_ASSERTE(_M_context._M_captureMethod != _S_captureDeferred);return(_M_context._M_pContextCallback !=nullptr);}
Pretty normal, right? Let's see how _ASSERTE is defined.

#ifndef _DEBUG...#ifndef _ASSERTE#define _ASSERTE(expr)((void)0)#endif/* _ASSERTE */...#else/* _DEBUG */...#ifndef _ASSERTE#define _ASSERTE(expr) _ASSERT_EXPR((expr), _CRT_WIDE(#expr))#endif/* _ASSERTE */...#endif/* _DEBUG */
This is good, right? Perform checks while testing; then, when most bugs have been weeded out, omit the tests for production, to reap major performance benefits. So speed! Such performance! Wheeee!

No. This is wrong. Do not do this.First of all: assert checks are nearly free. In most applications - i.e. anywhere outside of algorithms that do hard core, cache-optimized data crunching - the CPU is not tied up by instructions, it…

Why I use "SomeObj const&", not "const SomeObj&"

This is a minor point of style, but it's important to me.

For some reason, the widely accepted C++ style is to put const in front of things:

void Function(const std::vector<int>& v){constint i =123;...}
I pronounce this a bad choice. There's another legal way to use const, and I prefer it:

void Function(std::vector<int>const& v){intconst i =123;...}
This is why:

constvoid*const*const p =...;// Not so clear and consistentvoidconst*const*const p =...;// Clear and consistentvoid Method()const;// const comes after Method
When a pointer is const, the keyword comes after the asterisk. When a method is const, the keyword comes after the method. When a type is const, putting const after the type is always consistent.

Putting const in front, as per the usual style, makes things like:

constvoid*const*const p =...;
... kinda confusing.

Reporting errors in destructors

July 17, 2015:

My below suggestions are not good for C++11 in GCC, Clang, and probably VS 2015 and later.

See my follow-up post:

Errors in destructors: C++ and the case for aggregate exceptions


I'm having an argument with someone who thinks Effective C++ is the end-all and be-all of all things. Specifically: The book has a chapter on how exceptions in destructors are tricky. The guy appeals to this as an authority, and concludes you should never throw exceptions in destructors, ever.

Now, Effective C++ is a good book. I would recommend it to a beginner. If you're at a point where you need to read Effective C++, please do read it, get 3-5 more years of experience, and then give me a ring.

Shortly, though, the guy is wrong. All code has to be aware of exceptions. All code has to get them right. Destructors are just somewhat trickier, because they have to be more aware of them.

This doesn't mean you shouldn't throw from destructors. In fact, you should. The following code:

C++ should support temporary objects as lvalues

Microsoft Visual C++ has long implemented an extension to C++ that the standard language does not permit: temporary objects can be assigned to non-const references (lvalues).

I find this extension useful, allowing for some elegant constructs that standard C++ does not permit.


Example 1:

void StrCvtCp(Seq in, Str& out,UINT inCp,UINT outCp, Vect<wchar_t>& convertBuf);
Here I have a function that converts a string from one code page into another, using MultiByteToWideChar and WideCharToMultiByte internally. The function needs to use a conversion buffer. For callers that might call this function many times in a row, it is more efficient to keep reusing the same conversion buffer than to reallocate it in every call to the function. More occasional callers, however, don't want the inconvenience of having to instantiate the buffer, and just want one to be created by default.

In MSVC, solving this is easy:

void StrCvtCp(Seq in, Str& out,UINT inCodePage,UINT outCodePage, …