[comp.sys.ibm.pc.programmer] No Aliasing Compile Option

pipkins@qmsseq.imagen.com (Jeff Pipkins) (05/25/90)

My two cents worth (an inflated price, at that):

1. Because of the design of the C language, it is not possible for a C
compiler to completely detect all aliasing situations ("not possible" means
without spending potentially infinite amounts of time simulating the code,
of course).  Other languages have been designed specifically so that
the compiler can detect aliasing.  Unfortunately, this requires constraints
on the language that are so severe that the language becomes unsuitable
for professional use.  The "cost" is too high.

2. It is not "wrong" to use aliasing, either morally or legally, and it is
not generally considered bad practice.  Since I used the word "morally",
this is obviously my opinion.

3. Why is this compiler option there, anyway?  Because the compiler writer
says to himself (while writing the compiler), "DAMN!  If I could just make
this one little ASSumption, I could produce tighter code!  Wouldn't that
be nifty?!!"  But he knows that it is an UNSAFE optimization.  But he
still can't resist.  It would be so neat.  So he adds it as an option.
POINT: Not only should the option not be used to compile benchmarks, IT SHOULD
NOT EVEN BE AN AVAILABLE OPTION FOR THE COMPILER IN THE FIRST PLACE!
Unsafe optimizations are just that -- unsafe.  The option is there because
the compiler writer couldn't resist the temptation, and now he is passing
the temptation on to the user of the compiler by encouraging him to use
an unsafe option.  Tell me, how do you guarantee that the option doesn't
break your code?  Tell me how you have insured it is safe -- by looking
at it?  How do you test for that?  If it doesn't run correctly, does it
matter that it runs faster?  The only thing that should be done with
unsafe optimizations is to omit them.

<End of soapbox>

Jeff Pipkins
pipkins@imagen.com

chip@tct.uucp (Chip Salzenberg) (05/25/90)

According to al@unhd.unh.edu.UUCP (Anthony Lapadula):
>In article <265861D7.3293@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes:
>>Because aliasing is such a basic feature of the language, it is not
>>fair to clue in the compiler: "Psst!  This is one of those special
>>programs that doesn't do aliasing.  Unholster the benchmark gun."
>
>I suppose we should just give up helpful optimizations until
>the compiler is smart enough to figure out when aliasing isn't present?

Use whatever optimization you like for personal code.  My only
complaint is about the use of a C-subset compiler ("cc -Oa") to
compile published benchmark programs that are misrepresented as C
compiler benchmarks.

>Hmmmm.  How do you feel about "register"?  Is that cheating?

Nope.  It's a part of standard C.

>Just to add in my 2 cents, within the past year I've completed 2
>medium-sized programs (each ~10,000 lines) using MSC 5.1.
>I was quite please (surprised?  not quite) that the -Ox did *not*
>break a single line of code.

That's nice.  It's also irrelevant.  Just because other people
restrict themselves to a C subset does not make Microsoft right for
publishing C-subset benchmarks misrepresented as C benchmarks.
-- 
Chip Salzenberg at ComDev/TCT   <chip%tct@ateng.com>, <uunet!ateng!tct!chip>

kt4@prism.gatech.EDU (Ken Thompson) (05/25/90)

In article <134@qmsseq.imagen.com> pipkins@qmsseq.UUCP (Jeff Pipkins) writes:
>My two cents worth (an inflated price, at that):
>
>1. Because of the design of the C language, it is not possible for a C
>
[ lots of stuff deleted about why there should not be a no aliasing compiler
 option ]

I must again disagree. No one is requiring you to use this option. I 
personally have written many C programs that do not use aliasing. Why 
shouldn't I be able to take advantage of greater speed and tighter code. It
doesn't force you to use this option. 

					Ken


-- 
Ken Thompson  GTRI, Ga. Tech, Atlanta Ga. 30332 Internet:!kt4@prism.gatech.edu
uucp:...!{allegra,amd,hplabs,ut-ngp}!gatech!prism!kt4
"Rowe's Rule: The odds are five to six that the light at the end of the
tunnel is the headlight of an oncoming train."       -- Paul Dickson

mcdonald@aries.scs.uiuc.edu (Doug McDonald) (05/25/90)

In article <134@qmsseq.imagen.com> pipkins@qmsseq.UUCP (Jeff Pipkins) writes:
>POINT: Not only should the option not be used to compile benchmarks, IT SHOULD
>NOT EVEN BE AN AVAILABLE OPTION FOR THE COMPILER IN THE FIRST PLACE!

UTTER BULLSHIT. Belive me, I EXPECT that optimization to be present - 
if YOU don't like fast code, simply turn it off. I know how to 
code so it will not cause problems. Just pretend you are
writing, for instance, Fortran. I have NEVER had it break any of my code.

Doug McDonald

markro@microsoft.UUCP (Mark ROBERTS) (05/26/90)

In article <1913@cod.NOSC.MIL> bmarsh@cod.nosc.mil.UUCP (William C. Marsh)
writes:

>Example of a misuse of aliasing:
>
>int	test = 0, *int_ptr;
>int_ptr = &test;
>do {
>	*int_ptr = 1;
>} while (test == 0);
>
>This is a very simple example, but it represents the only area where MSC
>generated incorrect code in my 2.5 years using 5.X.  In my opinion, this 
>style of codeing is very bad, as it is very easy to forget that "*int_ptr"
>and "test" are the same thing (Well, not in *this* example ;-)

The detection of common aliasing practices has been improved in the
Microsoft C version 6.00 code generator. The primary difference is
that the compiler now tries to detect when the address of a variable
has been taken and then protect against aliasing corruption of that
variable even when the /Oa option is selected. If no option's are
selected that invoke the global optimizer, i.e. (/Oe, /Og, /Ol), the
optimizer depends on the preproccessor marking all variables that
have had their address taken (&). With global optimization the
optimizer itself does the necessary data flow analysis to determine
if an address has been taken. This makes /Oa safer when used in
conjunction with global optimization since it can detect addresses
being taken even in the absence of the address-of operator (&).

>I have three or four (four counting a graphics library) commercial software
>packages completed, *ALL* using -0a!

The C6 compiler is also compiled -Oxa, except for two functions where
it was more convenient to use #pragma optimize to turn off -Oa, rather 
than rewrite the code to remove the aliasing.

markro@microsoft.UUCP (Mark ROBERTS) (05/26/90)

In article <1913@cod.NOSC.MIL> bmarsh@cod.nosc.mil.UUCP (William C. Marsh) writes:
>In article <265861D7.3293@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes:
>>Now, if the compiler determines on its own that no aliasing is
>>possible, and then does the optimization on its own, then more power
>>to it.  That's great, because it will work for the individual routines
>>in my code in which no aliasing occurs.  But MSC isn't that smart yet.
>
>I don't beleive *any* compiler could be that smart.  Any routine that was
>passed a pointer couldn't use any global or static data, for fear that it
>is being aliased by the pointer.  The compiler, unless it looks at all the
>code (and all the possible ways of calling that function) could not possibly
>do this kind of optimization on it's own.

Actually, it is possible to do a pretty decent job of alias analysis; it is
just very computationaly expensive.  We have been investigating some
possibilities as an outgrowth of our interprocedural optimization research and
have developed an algorithm we think will work. Unfortunately, it is order n
to the power you don't even want to think about. And assumes an underlying
full interprocedural analysis to boot.

For now I think we're stuck with some sort of 'relax aliasing' option for
those wanting to get the most out of their compiler and willing to cooperate a
little bit with it.

[Now Preston can give us his 'why I like Fortran' spiel ;-) ]

Mark Roberts
{uw-beaver|uunet}!microsoft!markro
-- 
Send compilers articles to compilers@esegue.segue.boston.ma.us
{spdcc | ima | lotus}!esegue.  Meta-mail to compilers-request@esegue.
Please send responses to the author of the message, not the poster.

bcw@rti.rti.org (Bruce Wright) (05/28/90)

In article <134@qmsseq.imagen.com>, pipkins@qmsseq.imagen.com (Jeff Pipkins) writes:
> 2. It is not "wrong" to use aliasing, either morally or legally, and it is
> not generally considered bad practice.  Since I used the word "morally",
> this is obviously my opinion.

I don't know where you've been, but where _I've_ been it _has_ been
considered bad practice to use aliasing.  Not bad _morally_ or
_legally_ (how silly) but bad from a program maintenance point of
view:  it's difficult for someone other than the person who wrote
the code to understand, correct, and/or modify the code.  Sometimes
it can even be difficult for the person who wrote it (!).

A programmer who wrote the code in question should _know_ if aliasing
is being used;  the only valid excuse for not knowing would be that
the code had been inherited from someone else that had not used very
strict programming standards and/or didn't document what he/she had
been writing.

> 3. Why is this compiler option there, anyway?  Because the compiler writer
> says to himself (while writing the compiler), "DAMN!  If I could just make
> this one little ASSumption, I could produce tighter code!  Wouldn't that
> be nifty?!!"  But he knows that it is an UNSAFE optimization.  But he
> still can't resist.  It would be so neat.  So he adds it as an option.
> POINT: Not only should the option not be used to compile benchmarks, IT SHOULD
> NOT EVEN BE AN AVAILABLE OPTION FOR THE COMPILER IN THE FIRST PLACE!

It's also an UNSAFE assumption to optimize array references - strictly
speaking, you should have bounds checking on ALL array references
(C. A. R. Hoare has quite a bit to say about this).  Many people find
that this produces programs that run too slowly for their purposes,
and find it useful to have a switch to remove array bounds checking.

If you _really_ want to avoid this sort of thing, you should NOT be
using C!!!   It's just not possible to avoid possible problems of this
sort in anything remotely approaching the full language -- for example,
as soon as you use the ++ operator on a pointer, you have done an
operation semantically equivalent to an _unchecked array reference_.

Peter Norton once made the remark that C was an industrial strength
language, and that many people got the impression that what they
needed was an industrial strength language without realizing that
"industrial strength" also means "unsafe for children and small
animals".

> Tell me how you have insured it is safe -- by looking at it?

Ideally, you should attempt to show that the program _must_ be
correct (proof of correctness).  In practice this is often very
difficult, especially when pressed for time.  If you _don't_
have the time to at least give this a go and make the attempt, 
you probably shouldn't be using C. 

Maybe you should be using Ada.

						Bruce C. Wright

pipkins@qmsseq.imagen.com (Jeff Pipkins) (05/28/90)

Wow, major opinions!  Here we go one more time:

>I don't know where you've been, but where _I've_ been it _has_ been
>considered bad practice to use aliasing.  Not bad _morally_ or
>_legally_ (how silly) but bad from a program maintenance point of
>view:  it's difficult for someone other than the person who wrote
>the code to understand, correct, and/or modify the code.  Sometimes
>it can even be difficult for the person who wrote it (!).

I agree with the sentiment expressed here.  Maintenance and reliability
are the most important qualities of good code.  More important than
speed.

But anyone who has ever passed a pointer to a function, or written a
function that takes a pointer as an argument, has used aliasing!
Now, it's true that the compiler only cares about the names that exist
simultaneously in the same scope.  But if you write a function that
takes a pointer, and someone calls it by passing the address of a
global, that's aliasing.  (Of course, none of the respectable programmers
here would ever use globals anyway ;-).
-----------------------------------------------------------------------
>It's also an UNSAFE assumption to optimize array references - strictly
>speaking, you should have bounds checking on ALL array references
>(C. A. R. Hoare has quite a bit to say about this).  Many people find
>that this produces programs that run too slowly for their purposes,
>and find it useful to have a switch to remove array bounds checking.

>If you _really_ want to avoid this sort of thing, you should NOT be
>using C!!!   It's just not possible to avoid possible problems of this
>sort in anything remotely approaching the full language -- for example,
>as soon as you use the ++ operator on a pointer, you have done an
>operation semantically equivalent to an _unchecked array reference_.

>Peter Norton once made the remark that C was an industrial strength
>language, and that many people got the impression that what they
>needed was an industrial strength language without realizing that
>"industrial strength" also means "unsafe for children and small
>animals".

I think we are changing the subject slightly, but even though C is an
industrial-strength language, which makes it useful, that is no reason to
abuse it or to forego safe coding practices.  In fact, we should develop
habits that help us write safer code (that doesn't mean giving up power).
Here is my favorite example:

In general, you can encourage yourself to write more reliable code by
always using the braces {} in if-else statements, even if there is only
one line of code in them.  That is because there is a language ambiguity
that is resolved with semantics.  This semantic resolution can be avoided
by using the braces.  If you write this code:

    if (cond) 
       stmt1;
    else
       stmt2;

It will work fine until it is modified (by you or someone else) like so:

    if (cond) 
       if (cond2)
	  stmt1;
    else
       stmt2;

Now of course we should all argue that "someone else" is an idiot and
shouldn't modify it in such a way as to break it.  (now the else clause
sticks with the if (cond2).)  In this simple example it is easy to see
that it is incorrect.  In real-life examples, as you know, it is not
always so obvious.  But if the braces are always used, this can never
happen:

   if (cond) {
      stmt1;
   }else{
      stmt2;
   }

I'm not saying we should try to write code that nobody else can break
by modifying it -- that's obviously rediculous.  I'm just saying that
there are some simple things we can do to protect ourselves and make
our code safer in general.  If you always use the braces around everything,
you will never even have to check to see if there is a dangling else
problem.  You will know that there isn't.  And extra braces don't cost
anything at run time.

I'm way off the subject of aliasing now, but my theme is still the
idea that we can write safe code with C, without giving up any power to do it.
----------------------------------------------------------------------------
>>POINT: Not only should the option not be used to compile benchmarks, IT SHOULD
>>NOT EVEN BE AN AVAILABLE OPTION FOR THE COMPILER IN THE FIRST PLACE!

>UTTER BULLSHIT. Belive me, I EXPECT that optimization to be present - 
>if YOU don't like fast code, simply turn it off. I know how to 
>code so it will not cause problems. Just pretend you are
>writing, for instance, Fortran. I have NEVER had it break any of my code.

Did I say that I didn't like fast code?  I just said that I preferred code
that works over that which doesn't, but is faster.  If you truly want
your code to be faster, significantly faster, you replace an algorithm
with one that is more efficient.  Like use a quicksort instead of that
selection (or bubble (gasp)) sort.  Replace that sequential search with
a binary search, or replace the binary search with a hash table.
Code "squeezing" only buys you a little efficiency in comparison.
I realize that I don't have to use the -Oa option.  That wasn't really
the point.  The point was that the author of a program (in this case,
a compiler) should not encourage its users to abuse it.  IMHO, that
is what -Oa is about.

=============================================================================
Jeff Pipkins
pipkins@imagen.com
My opinions are not necessarily shared by anyone, as is apparent from the
responses to my last posting ;-).  I appreciate hearing from those with
different views.

dmurdoch@watstat.uwaterloo.ca (Duncan Murdoch) (05/29/90)

In article <3866@rtifs1.UUCP> bcw@rti.rti.org (Bruce Wright) writes:
>In article <134@qmsseq.imagen.com>, pipkins@qmsseq.imagen.com (Jeff Pipkins) writes:
>> 2. It is not "wrong" to use aliasing, either morally or legally, and it is
>> not generally considered bad practice.  Since I used the word "morally",
>> this is obviously my opinion.
>
>I don't know where you've been, but where _I've_ been it _has_ been
>considered bad practice to use aliasing.  Not bad _morally_ or
>_legally_ (how silly) but bad from a program maintenance point of
>view:  it's difficult for someone other than the person who wrote
>the code to understand, correct, and/or modify the code.  Sometimes
>it can even be difficult for the person who wrote it (!).

Is it considered to be aliasing to have two pointers pointing at the same
thing?  This seems to be a very useful and common practice; think about 
having an array sorted in two different ways:  you usually wouldn't want
two copies of the data (especially if you want to modify the entries!), 
you'd probably just want two arrays of pointers into it.  Does this sort
of practice fail when aliasing isn't allowed?

Duncan Murdoch

chip@tct.uucp (Chip Salzenberg) (05/30/90)

According to bmarsh@cod.nosc.mil.UUCP (William C. Marsh):
>Sure, I can program in a very poor style, and a 'true' C
>compiler will still compile it correctly, but is that really
>what you want?

YES.  That's EXACTLY what I want.  I paid for a C compiler,
right?  I want to get what I paid for.

PLEASE NOTE: My complaint is that Microsoft is using "cl -Oa" in
PUBLISHED BENCHMARKS.  I consider this practice EVIL and RUDE,
because "cl -Oa" is not a C compiler.  It produces incorrect
results on C programs that use aliasing within functions.  Such
programs may be poorly written in the opinion of some, but they
are still *valid* C programs.

If I read a Microsoft C benchmark result, I want it to be
compiled with a COMPLETE C COMPILER.  To do otherwise is
fraudulent advertising on Microsoft's part.

Is that clear enough?
-- 
Chip, the new t.b answer man    <chip%tct@ateng.com>, <uunet!ateng!tct!chip>

chip@tct.uucp (Chip Salzenberg) (05/30/90)

According to mcdonald@aries.scs.uiuc.edu (Doug McDonald):

>Belive me, I EXPECT that optimization to be present - if YOU don't
>like fast code, simply turn it off. I know how to code so it will not
>cause problems. Just pretend you are writing, for instance, Fortran.

To paraphrase Dennis Ritchie:

   If you want FORTRAN, you know where to find it.

I'll use the *entire* C language, thank you.

-- 
Chip, the new t.b answer man    <chip%tct@ateng.com>, <uunet!ateng!tct!chip>

chip@tct.uucp (Chip Salzenberg) (05/30/90)

According to bcw@rti.rti.org (Bruce Wright):
>In article <134@qmsseq.imagen.com>, pipkins@qmsseq.imagen.com (Jeff Pipkins) writes:
>> Not only should ["-Oa"] not be used to compile benchmarks, IT SHOULD
>> NOT EVEN BE AN AVAILABLE OPTION FOR THE COMPILER IN THE FIRST PLACE!
>
>It's also an UNSAFE assumption to optimize array references [...]

Program safety is not the issue.

Complete implementation of the C language is the issue.

All relevant C documents permit unrestricted aliasing,
as well as the "goto" statement and other features not
often used by experienced and careful programmers.
Nevertheless, a C compiler must support ALL features of
the C language to be called a C compiler.

Ergo, "cl -Oa" is not a C compiler, and Microsoft should
stop using it in published benchmarks that claim to show
results for the "Microsoft C Compiler."
-- 
Chip, the new t.b answer man    <chip%tct@ateng.com>, <uunet!ateng!tct!chip>

coy@ssc-vax.UUCP (Stephen B Coy) (06/02/90)

This discussion has gotten a bit overblown.  Please read my comments
with a healthy dose of :-)'s.

In article <2663F3E5.725E@tct.uucp>, chip@tct.uucp (Chip Salzenberg) writes:
> PLEASE NOTE: My complaint is that Microsoft is using "cl -Oa" in
> PUBLISHED BENCHMARKS.  I consider this practice EVIL and RUDE,
> because "cl -Oa" is not a C compiler.  It produces incorrect
> results on C programs that use aliasing within functions.  Such
> programs may be poorly written in the opinion of some, but they
> are still *valid* C programs.

This implies that any compiler with a bug, no matter how obscure or
easy to work around is "not a real(tm) C compiler."  I'll bet that
most compiler vendors also run their benchmarks with trigraph
recognition turned off to save time in their lexer.  More EVIL and
RUDE practice to be sure.  But should that bother you?  When was the
last time you needed trigraphs?

Running benchmarks with -Oa is valid because most code can take
advantage of extra speed gain just as compiling without trigraphs is
valid since trigraph recognition tends to be extra baggage in the
great majority of cases.

> If I read a Microsoft C benchmark result, I want it to be
> compiled with a COMPLETE C COMPILER.  To do otherwise is
> fraudulent advertising on Microsoft's part.

Last time I checked MSC still wasn't 100% ANSI compliant.  Close
enough for real work but not a COMPLETE C COMPILER.  Note that this
also applies to all the other "C" compilers on the market.

> Is that clear enough?

One comment.  With all the variables involved in benchmarking
compilers I'm surprised anybody would even believe a vendor's
benchmarks have any validity whatsoever.  A good first step would be
to check out what Computer Language or other magazines have to say
when they compare compilers.  The only realistic approach is to try
your own code.

> Chip, the new t.b answer man    <chip%tct@ateng.com>, <uunet!ateng!tct!chip>

Stephen Coy 
uw-beaver!ssc-vax!coy

wwg@brambo.UUCP (Warren W. Gay VE3WWG) (06/05/90)

>In article <265A8814.1465@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes:
>[[ Please note that the -Ox flag of MSC 6.0 is now safe.  However,
>   unsafe aliasing optimization is still available with the -Oa flag.
>   The target of my criticism is the use of -Oa in compiling
>   advertising benchmarks. ]]
>...bunch of stuff removed...
>
>Nevertheless, I stand by my assertion that the use of a "benchmark
>flag" (-Oa) is reprehensible on Microsoft's part--doubly so, since
>they didn't print in large friendly letters, THIS BENCHMARK IS
>COMPILED WITH A NO-ALIASING OPTION THAT YOU MAY NOT BE ABLE TO USE FOR
>YOUR OWN CODE.


I'm coming into this fray rather late, but hey-- at least they didn't
use the "#asm" optimization feature! :-)

You are arguing at cross purposes. Unless u are in agreement about what
is being measured, the argument is pointless.

	"What should the benchmark measure?"

The possibilities include:

	1.	Default compiles.
	2.	Safe optimized compiles.
	3.	Flat out capability.


I believe that all 3 measurements are useful. Measurement # 2 is 
probably the most important, especially when existing code is to be
RE-compiled and/or ported. If only one set of benchmarks are going to be
published, then I tend to think that this should be the figure to publish
(but again, we have to agree on what is being measured first).

However, if I was to purchase a product, and assuming that I also want to
spend the time tweaking (or can justify doing so), then the all out, flat
out "measurements" are also highly significant. This becomes a test of
the "capability" of the compiler-- just how far can it go if I NEED it.

If I went with "safe optimization" only compiler (or options), then I'd
be forced to go to MASM more often. Given the choices-- I'd much rather
use a "subset C" when I need to, then be stuck to a principle.

*flame*suit*on*

After all, referring thru a pointer is equally valid C code. So why INSIST
on aliasing in the first place?  ;-)

*flame*suit*off*

--... ...-- ...                           VE3WWG @ VE3HPL : AX.25
          Bramalea Software Systems Inc...  !utgpu!telly \ !brambo!wwg
               !{uunet!mnetor, watmath!utai}!lsuc!ncrcan /
                   utzoo!telly!brambo!wwg@ai.toronto.edu : Internet

shap@bunker.UUCP (Joseph D. Shapiro) (06/05/90)

In article <250@demott.COM> kdq@demott.COM (Kevin D. Quitt) writes:
>    Unless I'm greatly mistaken, the only problem for optimization with
>aliasing involves the use of a variable and its alias *within the same
>function*.  Calling a function with a pointer doesn't hurt, since the
>compiler can know that variables may not be preserved across the
>function call.  I've used the aliasing release on programs that follow
>this model with nary a problem.

how about the following....

In file a.c

	static int foo;

	main()
	{
		bar(foo);
	}

	baz()
	{
		foo++;
	}

in file b.c

	foo(int x)
	{
		... establish a value for x here ...
		baz();
		... reference x here ...
	}

is this not aliasing as well?
will not -Oa cause trouble in b.c?
-- 
__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__--__
Joe Shapiro					"My other car is a turbo...
ISC-Bunker Ramo     				 ...too."
{decvax,yale,philabs,oliveb}!bunker!shap

markro@microsoft.UUCP (Mark ROBERTS) (06/06/90)

In article <12215@bunker.UUCP> shap@clunker.UUCP (Joseph D. Shapiro) writes:
>In file a.c
>
>	static int foo;
>
>	main()
>	{ bar(foo); }
>
>	baz()
>	{ foo++; }
>
>in file b.c
>
>	foo(int x)
>	{ ... establish a value for x here ...
>		baz();
> 	  ... reference x here ...
>	}
>
>is this not aliasing as well?
>will not -Oa cause trouble in b.c?

Well, sort of.  I think you have a couple of problems with your example -
the function foo should be named bar and since ints are passed by value 
there can be no aliasing.  But, try this:
	static int foo;

	main()
	{ bar(&foo); }

	baz()
	{ foo++; }

	int bar(int *x)
	{
		*x=3;
		baz();
		return *x;
	}

Now you've got aliasing and -Oa will fail, even in same file.  But is it
the same example?  Do people really write code like this?  I would certainly
not encourage this, but no doubt its done.  In which case, you can't use
-Oa; however, -Ow would work.