Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Forcing compile-time error

Reply
Thread Tools

Re: Forcing compile-time error

 
 
Stargazer
Guest
Posts: n/a
 
      06-11-2010
On Jun 11, 4:53*pm, Kenneth Brody <(E-Mail Removed)> wrote:
> I know about the #error directive, but it can't be used in this case...
>
> I am replacing calls to an outdated system function with a new wrapper
> function which can be updated as needed. *(ie: if the "new" system function
> gets obsoleted down the road, it can be replaced in a single location.) *All
> of the source code is being updated to use the new wrapper function, but I
> would like to catch any missed calls to the old function, and fail at
> compile time.
>
> For example:
>
> * * *x = OldFunction(foo,bar);
> is replaced with:
> * * *x = NewFunctionWrapper(foo,bar,baz);
>
> Suppose there is some line, somewhere in the source, which was missed. *Is
> it possible to force a compile-time error at that line?
>
> I know that the following is invalid, but it's the kind of thing I would
> want to be able to do:
>
> * * *#define OldFunction(foo,bar) #error OldFunction called __FILE__ __LINE__


Just #define OldFunction to syntactically erroneous expression, e.g.

#define OldFunction(foo,bar) (1 = foo, 3 = bar)

Most compilers are smart enough to diagnose precise line, source file
and macro name.
Put the definition in the header that includes function prototype or
your own headers.

>
> I was thinking of something like this, but it just seems... ugly.
>
> * * *#define OldFunction(foo,bar) {***__OldFunction__ called!***;}
>
> Another problem with this version is that the macro would have to be in
> every source file (obviously), but _after_ the "normal" #includes, as
> OldFunction is prototyped in the (standard other than C) header files which
> are included.


Didn't get a reason of this requirement. Anyway, you may limit the
effect of erroneous definition to your sources only, something like

#ifdef MY_SOURCE
#define OldFunction(foo,bar) {***__OldFunction__ called!***;}
#endif

in the system header, and put

#define MY_SOURCE

at first line of all your sources.

Daniel
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      06-11-2010
On 6/11/2010 5:24 PM, Stargazer wrote:
> On Jun 11, 4:53 pm, Kenneth Brody<(E-Mail Removed)> wrote:
>> I know about the #error directive, but it can't be used in this case...
>>
>> I am replacing calls to an outdated system function with a new wrapper
>> function which can be updated as needed. (ie: if the "new" system function
>> gets obsoleted down the road, it can be replaced in a single location.) All
>> of the source code is being updated to use the new wrapper function, but I
>> would like to catch any missed calls to the old function, and fail at
>> compile time.
>>
>> For example:
>>
>> x = OldFunction(foo,bar);
>> is replaced with:
>> x = NewFunctionWrapper(foo,bar,baz);
>>
>> Suppose there is some line, somewhere in the source, which was missed. Is
>> it possible to force a compile-time error at that line?
>>
>> I know that the following is invalid, but it's the kind of thing I would
>> want to be able to do:
>>
>> #define OldFunction(foo,bar) #error OldFunction called __FILE__ __LINE__

>
> Just #define OldFunction to syntactically erroneous expression, e.g.
>
> #define OldFunction(foo,bar) (1 = foo, 3 = bar)
>
> Most compilers are smart enough to diagnose precise line, source file
> and macro name.
> Put the definition in the header that includes function prototype or
> your own headers.
>
>>
>> I was thinking of something like this, but it just seems... ugly.
>>
>> #define OldFunction(foo,bar) {***__OldFunction__ called!***;}
>>
>> Another problem with this version is that the macro would have to be in
>> every source file (obviously), but _after_ the "normal" #includes, as
>> OldFunction is prototyped in the (standard other than C) header files which
>> are included.

>
> Didn't get a reason of this requirement.


Because if the macro is in force when the system header utters
its prototype

void OldFunction(int this, double that);

.... the macro will change it to

void (1 == int this, 2 = double that);

.... right at the point of the header's declaration. This causes a
compile error (as desired), but for every file that includes the
header, whether it uses OldFunction or not.

> Anyway, you may limit the
> effect of erroneous definition to your sources only, something like
>
> #ifdef MY_SOURCE
> #define OldFunction(foo,bar) {***__OldFunction__ called!***;}
> #endif
>
> in the system header, [...]


Most programming shops take a dim view of hand-editing the
system-supplied headers. Too much opportunity for mischief (both
intentional and accidental), and also susceptible to being clobbered
by the next vendor-supplied patch ...

It seems to me that the compiler is not the right tool for this
job. It is tempting to (ab)use the compiler as a software quality
enforcer; I've yielded to the temptation more than once, but have
always wound up regretting it. Rather, I'd agree with Keith Thompson
and others that a grep or equivalent will be more direct and more
effective. True, it won't catch everything: An OldFunction reference
built by token-pasting, for example, would elude a simple search. But
it will catch all but the most contrived cases -- and if repeated as
part of the standard build and/or check-in procedure, it will catch
accidental re-introductions in the future, too.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid
 
Reply With Quote
 
 
 
 
Stargazer
Guest
Posts: n/a
 
      06-12-2010
On Jun 12, 1:14*am, Eric Sosman <(E-Mail Removed)> wrote:
> On 6/11/2010 5:24 PM, Stargazer wrote:
>
>
>
>
>
> > On Jun 11, 4:53 pm, Kenneth Brody<(E-Mail Removed)> *wrote:
> >> I know about the #error directive, but it can't be used in this case....

>
> >> I am replacing calls to an outdated system function with a new wrapper
> >> function which can be updated as needed. *(ie: if the "new" system function
> >> gets obsoleted down the road, it can be replaced in a single location.) *All
> >> of the source code is being updated to use the new wrapper function, but I
> >> would like to catch any missed calls to the old function, and fail at
> >> compile time.

>
> >> For example:

>
> >> * * * x = OldFunction(foo,bar);
> >> is replaced with:
> >> * * * x = NewFunctionWrapper(foo,bar,baz);

>
> >> Suppose there is some line, somewhere in the source, which was missed. *Is
> >> it possible to force a compile-time error at that line?

>
> >> I know that the following is invalid, but it's the kind of thing I would
> >> want to be able to do:

>
> >> * * * #define OldFunction(foo,bar) #error OldFunction called __FILE__ __LINE__

>
> > Just #define OldFunction to syntactically erroneous expression, e.g.

>
> > #define OldFunction(foo,bar) (1 = foo, 3 = bar)

>
> > Most compilers are smart enough to diagnose precise line, source file
> > and macro name.
> > Put the definition in the header that includes function prototype or
> > your own headers.

>
> >> I was thinking of something like this, but it just seems... ugly.

>
> >> * * * #define OldFunction(foo,bar) {***__OldFunction__ called!***;}

>
> >> Another problem with this version is that the macro would have to be in
> >> every source file (obviously), but _after_ the "normal" #includes, as
> >> OldFunction is prototyped in the (standard other than C) header files which
> >> are included.

>
> > Didn't get a reason of this requirement.

>
> * * *Because if the macro is in force when the system header utters
> its prototype
>
> * * * * void OldFunction(int this, double that);
>
> ... the macro will change it to
>
> * * * * void (1 == int this, 2 = double that);
>
> ... right at the point of the header's declaration. *This causes a
> compile error (as desired), but for every file that includes the
> header, whether it uses OldFunction or not.


This will happen only if

#define OldFunction(foo,bar) (1 = foo, 3 = bar)

occurs before OldFunction()'s declaration in the header; so it should
appear after #include to that system header or in the header *after*
the declaration of OldFunction().

Usually projects have their own "common" headers that all developed
code include. So such a definition can be put in "project-header.h",
which will also include the system header in question (let's call it
"system-header.h").

E.g.

---------- project-header.h -------------
#include "system-header.h"
//...
#define OldFunction(foo,bar) (1 = foo, 3 = bar)
//...
-----------------------------------------

If desired, "project-header.h" can ensure that "system-header.h"
hasn't been already included, assuming that system header is protected
agains multiple inclusion, say, with

#ifndef SYSTEM_HEADER_H
#define SYSTEM_HEADER_H
//... Header contents
#endif

---------- project-header.h -------------
#ifdef SYSTEM_HEADER_H
#error <<system-header.h>> was already included
#endif
#include "system-header.h"
//...
#define OldFunction(foo,bar) (1 = foo, 3 = bar)
//...
-----------------------------------------

> > Anyway, you may limit the
> > effect of erroneous definition to your sources only, something like

>
> > #ifdef MY_SOURCE
> > #define OldFunction(foo,bar) {***__OldFunction__ called!***;}
> > #endif

>
> > in the system header, [...]

>
> * * *Most programming shops take a dim view of hand-editing the
> system-supplied headers. *Too much opportunity for mischief (both
> intentional and accidental), and also susceptible to being clobbered
> by the next vendor-supplied patch ...


True. But sometimes (much more often than I would actually like it to
occur) vendors won't supply you anything unless you prove them "beyond
any doubt" that they have a bug. They wouldn't even acknowledge that
they have a bug unless you prove it. In such a case a programmer has
only two options: declare that there's a problem and nothing can be
done about it, or use any existing instrument to do the diagnosis.

> * * *It seems to me that the compiler is not the right tool for this
> job. *It is tempting to (ab)use the compiler as a software quality
> enforcer; I've yielded to the temptation more than once, but have
> always wound up regretting it. *Rather, I'd agree with Keith Thompson
> and others that a grep or equivalent will be more direct and more
> effective. *True, it won't catch everything: An OldFunction reference
> built by token-pasting, for example, would elude a simple search. *But
> it will catch all but the most contrived cases -- and if repeated as
> part of the standard build and/or check-in procedure, it will catch
> accidental re-introductions in the future, too.


Well, for just the job that OP requested I would first try to use find
+grep in order to locate all appearances of "OldFunction". The
utilities are today available on all build systems that I know,
including Windows. Most compilers today include some option to emit
proprocessor output, so as part of build grep may be applied to such
output, catching even references to OldFunction made by replacement of
"#define mkfuncname (name) Old##name". But... we still don't know
enought the OP's obstacles and needs, so as they say :

"Trust the programmer."
"Donít prevent the programmer from doing what needs to be done."

Daniel
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      06-12-2010
On 6/12/2010 7:54 AM, Stargazer wrote:
> On Jun 12, 1:14 am, Eric Sosman<(E-Mail Removed)> wrote:
>> On 6/11/2010 5:24 PM, Stargazer wrote:
>>> On Jun 11, 4:53 pm, Kenneth Brody<(E-Mail Removed)> wrote:
>>>> [...]
>>>> I was thinking of something like this, but it just seems... ugly.

>>
>>>> #define OldFunction(foo,bar) {***__OldFunction__ called!***;}

>>
>>>> Another problem with this version is that the macro would have to be in
>>>> every source file (obviously), but _after_ the "normal" #includes, as
>>>> OldFunction is prototyped in the (standard other than C) header files which
>>>> are included.

>>
>>> Didn't get a reason of this requirement.

>>
>> Because if the macro is in force when the system header utters
>> its prototype
>>
>> void OldFunction(int this, double that);
>>
>> ... the macro will change it to
>>
>> void (1 == int this, 2 = double that);
>>
>> ... right at the point of the header's declaration. This causes a
>> compile error (as desired), but for every file that includes the
>> header, whether it uses OldFunction or not.

>
> This will happen only if
>
> #define OldFunction(foo,bar) (1 = foo, 3 = bar)
>
> occurs before OldFunction()'s declaration in the header; so it should
> appear after #include to that system header or in the header *after*
> the declaration of OldFunction().


Right. Isn't that the requirement you "didn't get a reason of?"

> [...]
>>> Anyway, you may limit the
>>> effect of erroneous definition to your sources only, something like

>>
>>> #ifdef MY_SOURCE
>>> #define OldFunction(foo,bar) {***__OldFunction__ called!***;}
>>> #endif

>>
>>> in the system header, [...]

>>
>> Most programming shops take a dim view of hand-editing the
>> system-supplied headers. Too much opportunity for mischief (both
>> intentional and accidental), and also susceptible to being clobbered
>> by the next vendor-supplied patch ...

>
> True. But sometimes (much more often than I would actually like it to
> occur) vendors won't supply you anything unless you prove them "beyond
> any doubt" that they have a bug. They wouldn't even acknowledge that
> they have a bug unless you prove it. In such a case a programmer has
> only two options: declare that there's a problem and nothing can be
> done about it, or use any existing instrument to do the diagnosis.


The O.P. didn't say anything about OldFunction() being buggy;
he just called it "outdated." That is, there's nothing "wrong" with
the system header; it's just that one project has decided to migrate
to using the newer/better/whiter/brighter interface exclusively, and
would like to police itself. Also, the O.P. did not imply that this
migration was to apply to all projects; others may still want and need
to use the older interface.

Plus, as I mentioned earlier, the vendor might perfectly well
issue a new version of the header in a patch, still retaining the old
interface for backwards compatibility, so any local edits are vulnerable
to being overwritten.

To summarize, nothing you've said convinces me that modifying the
implementation is either wise or effective. YMMV -- but in the end,
the decision is not up to either of us.

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Calling Page in VB.NET class? and Forcing a page error? jobs ASP .Net 1 11-14-2007 01:17 AM
forcing cookies to use SSL and redirecting to custom error page =?Utf-8?B?RGFuIEtyYWltYW4=?= ASP .Net 0 12-30-2005 04:22 PM
forcing one connection Blacklab Wireless Networking 5 10-08-2005 01:21 AM
Forcing native 802.1x supplicant to re-auth??! Tony Wireless Networking 3 07-07-2004 11:35 PM
forcing a compile time error Michael Gaab C++ 8 11-09-2003 09:25 AM



Advertisments