Holy cow, I wrote a book!
One evening, I had a series of three dreams.
In each one, I visited an unusual home.
In the third dream, I visited the home of a friend of mine.
He lived in a white stucco split-level,
a stereotypical suburban home.
What made the house interesting was that if you did things
dark dots would appear on the wall and slowly consume it.
My friend explained,
"This house is running a very old build of DirectX,
and sometimes it just does that."
We set up a repro and calculated that when the dots appeared,
stack usage was exactly 5124 bytes.
This was a 16-bit house,
and the stack overflow into the heap caused a return address
to be changed to point into the DirectDraw flood fill function.
When I told my friend about this strange dream,
"I've since then upgraded to a 64-bit house."
In response to a description of what happens when you get
"This seems like a problem for the CRT.
As far as I know,
VC gives you the option of statically or dynamically linking the CRT.
But it seems like the headers will have to make a choice to support
one thing better than the other.
Conditional compilation would work,
but then people would have to remember to include a #define somewhere.
Is this dllimport vs. static linking thing something the compiler could figure out on its own if you're doing Link-time codegen?"
Let's start from the beginning.
Yes, this would be a problem for the CRT since it wouldn't know whether
to declare the functions as normal static functions or as
and the headers have to make a choice which way to go.
And if you look at the headers, you can see that it is indeed done
via conditional compilation.
_CRTIMP int __cdecl fflush(FILE * _File);
This magic _CRTIMP symbol is defined in
crtdefs.h like so:
/* Define _CRTIMP */
#define _CRTIMP __declspec(dllimport)
#else /* _DLL */
#endif /* _DLL */
#endif /* _CRTIMP */
Conditional compilation decides whether _CRTIMP
expands to __declspec(dllimport) or to nothing at all,
depending on whether the _DLL symbol is defined.
And yet nobody bothers writing #define _DLL before
they #include <stdio.h>.
There must be something else going on.
In fact, we can run some experiments to see what's going on.
#error "_DLL is defined"
#error "_DLL is not defined"
Save this as dummy.c and run a few tests.
C:\tests> cl /MT dummy.c
dummy.c(4) : fatal error C1189: #error : "_DLL is not defined"
C:\tests> cl /MD dummy.c
dummy.c(2) : fatal error C1189: #error : "_DLL is defined"
Well how's about that.
The compiler uses the /MT and /MD
flag to decide whether or not to define the preprocessor symbol
_DLL, which is the secret signal it passes to the
crtdef.h header file to control the conditional
The compiler has to use this technique
instead of deferring the decision to link-time code generation
because it cannot assume that everybody has enabled link-time
(Indeed, we explicitly did not in our sample command lines.)
If link-time code generation were enabled, then is this something
that could be deferred until that point?
In principle yes,
because link-time code generation in theory could just make the .obj
file a copy of the source file (and all the header files) and do
all the actual compiling at link time.
This is a sort of extreme way of doing it,
but I guess it could've been done that way.
On the other hand, it also means that the compiler folks would have
to come up with a new nonstandard extension that means "This function
might be a normal static function or it might be a
function. I haven't decided yet; I'll tell you later."
Seeing as how the CRT already has to solve the problem in the case
where there is no link-time code generation, it doesn't seem worth
the effort to add a feature to link-time-code generation
that you don't actually need.
It would be a feature for which the only client is the C runtime
library itself, for which the C runtime library already requires
a separate solution when link-time code generation is disabled,
and for which that separate solution still works when link-time
code generation is enabled.
No engineering purpose is served by
writing code just for the sake of writing code.
On an internal discussion group,
somebody decided to quote one of my blog entries.
was amused by my response:
Bloggers are just idiots with a Web site.
(My blog was dug up in order to refute a claim,
even though the blog entry applied to a situation different from
the one under discussion.)
(The headline was stolen from one of my cleverer friends.)
I'm taking time out of my busy vacation to draw your attention
(if it hasn't been already) to the story of
South Korean fencer Shin A Lam,
got screwed out of her trip to the finals of the
women's individual epeé.¹
The story is heart-wrenching,
and the photojournalism is moving in its simplicity.
(Assisted in large part by the rule that fencers must not leave
the piste while the appeal is in progress.)
The FIE, fencing's international governing body,
later chose to
award Shin a special medal
"For aspiration to win and respect of the rules."
Apparently, the FIE's timekeeping equipment was not up to the task
"They never expected this kind of thing to happen in the last second,
Their timekeeping machine is only in seconds, not points of a second."
Because nobody expected fencing to have
sudden bursts of intense, frantic activity
which require split-second accuracy.
¹ To avoid matches which last indefinitely, fencing has
a concept known as priority:
Before the final overtime round, one of the fencers is chosen
at random to have priority.
If no winner is determined by the final round,
then the fencer with priority is declared the winner.
Shin had priority, so if the ruling had been no-touch,
she would have been the one to advance.
Meetings are so passé.
You no longer have a meeting with a customer;
you have an engagement:
I have a customer engagement tomorrow and they have a question
surrounding Feature X.
Note that this use of the phrase customer engagement
is different from the process known as customer engagement.
The process is an ongoing interaction,
a long-term activity to build customer loyalty.
The author of the above sentence is not using it in the
(because you don't have "a" customer engagement;
rather, a meeting is one component of the overall process of
Nope, the author is just trying to sound cool.
the modern quandary of preparing a dinner for people who
all have different types of dietary restrictions.
Depending on whom I invite to dinner, I may have to
put together a meal that conforms to one or more of the
following restrictions: low-fat, pescetarian, vegetarian, nondairy,
(Yes, many of these categories overlap.)
To the best of my knowledge, none of my dinner guests have
had nut allergies or been gluten intolerant.
I remember telling a story once and mentioning that the subject of the
story was a vegetarian.
The person I was telling the story to
(who is from an older generation)
"Are they so poor that they can't afford meat?"
Because in an older era,
people were vegetarians because they had no choice.
interviews Martin Lindstrom,
Buyology: Truth and Lies About Why We Buy
(another book in the series
Short catchy title: Long boring subtitle)
how stores get people to buy more stuff
by taking advantage of how our brains are wired.
(Unfortunately, at the time I checked, the
Smell and Beer bonus tracks were broken.
You can try to console yourself with Paddy Hirsch's
explanation of margin calls in terms of Girl Scout Cookies.)
Update: The Smell and Beer links work now.
Why have a conversation when you can dialogue?
I think this is minimal work,
but do others care?
If they don't, then this is one for the ideas that failed bin.
If they do, well let's dialogue...
No need to talk when you can dialogue.
A customer was encountering a problem with lots of duplicate GUIDs.
How is that possible?
The whole point of
the GUID generation algorithm
is to work hard
to avoid duplication.
Was one of the fundamental assumptions of the algorithm broken?
Maybe there was a duplicate MAC?
Was the clock regressing?
One of my colleagues pointed out that in the search for the subtle
source of the problem, you sometimes overlook the obvious one.
In fact, this is the most common source of problems with
so-called duplicate GUIDs.
As he so tersely puts it:
"A GUID can easily be duplicated by simply copying it."
In other words, you have a duplicate GUID because you duplicated
This can happen, for example, if you have a Clone
method on an object which creates an exact duplicate of the object.
Since the GUID is a property of the object, it too gets cloned.
Then you add the clone to the same database as the original.
Boom, instant duplicate.
It's that time again: Linking to other Microsoft bloggers.