Unignorable return value

G

gw7rib

If I have a function returning int, then I am free to ignore that
return value. For instance:

int fun(void);
x = fun(); // valid
fun(); // valid

If I want the former form to be invalid, I can instead make the
function of type void:

void fun(void);
x = fun(); // invalid
fun(); // valid

But supose I have a function where I don't want the return value to be
ignored. Is there any way I can do this? For instance:

unignorable int fun(void);
x = fun(); // valid
fun(); // invalid

The reason I would like such a thing is this. I am writing a program
that has "notes", and there is an option to edit the properties of a
note. One thing that can be edited is that you can associate a file
with the note, so it shows the text of that file. If you associate a
file with a note for the first time, or change the file associated
with a note, then depending on the details the note may or may not
need repainting, as its text content has changed. But, in a new
modification, you can also have an image associated with a note, which
can optionally be shown instead of the text, and if you change the
image associated with a note, or change it from showing the image to
showing the text or vice versa, it again will need repainting. At
present the routine handling the change of file name will repaint the
note if necessary. But if the user makes both changes then this can
result in the note being repainted twice, the first time incorrectly
as it has not yet taken all the changes into account. So I am
considering moving the repaint up into the edit properties routine, so
that there will be one repaint afterwards if either or both of the
subroutines say it is necessary. Since the subroutines thus lose
direct control over whether the repaint happens, I would like to
ensure that their return value (indicating whether it is required) is
not ignored to make it harder for me to mess this up.

Any thoughts welcome!

Thanks.
Paul.
 
V

Victor Bazarov

If I have a function returning int, then I am free to ignore that
return value. For instance:

int fun(void);
x = fun(); // valid
fun(); // valid

If I want the former form to be invalid, I can instead make the
function of type void:

void fun(void);
x = fun(); // invalid
fun(); // valid

But supose I have a function where I don't want the return value to be
ignored. Is there any way I can do this? For instance:

unignorable int fun(void);
x = fun(); // valid
fun(); // invalid

There is no way. Even if you force the caller of the function to get
the value, what makes you think the caller is going to do anything about
the value it gets?

int unignorable fun();
...
int dummy = fun();
// go on with our processing without paying attention to 'dummy'
The reason I would like such a thing is this. I am writing a program
that has "notes", and there is an option to edit the properties of a
note. One thing that can be edited is that you can associate a file
with the note, so it shows the text of that file. If you associate a
file with a note for the first time, or change the file associated
with a note, then depending on the details the note may or may not
need repainting, as its text content has changed. But, in a new
modification, you can also have an image associated with a note, which
can optionally be shown instead of the text, and if you change the
image associated with a note, or change it from showing the image to
showing the text or vice versa, it again will need repainting. At
present the routine handling the change of file name will repaint the
note if necessary. But if the user makes both changes then this can
result in the note being repainted twice, the first time incorrectly
as it has not yet taken all the changes into account. So I am
considering moving the repaint up into the edit properties routine, so
that there will be one repaint afterwards if either or both of the
subroutines say it is necessary. Since the subroutines thus lose
direct control over whether the repaint happens, I would like to
ensure that their return value (indicating whether it is required) is
not ignored to make it harder for me to mess this up.

Any thoughts welcome!

The paragraph above is too long for me to comprehend. But one thing I
get out of reading it (yes, I read it, just couldn't comprehend it):
you're going about it in a wrong way. You need to list the requirements
and then see what *you* can do about satisfying them, not the *user* of
your library.

It's like trying to force the user to deallocate the memory allocated in
the library. Give me the pointer, document the need to use 'delete' on
it, and some will still forget to do (or deliberately omit in some
cases) the deallocation. And even if you return 'std::auto_ptr', there
are still ways around the deallocation.

Don't force the user of your library into something. Provide a clear
mechanism, clear documentation, and a disclaimer, and hope they do The
Right Thing(tm).

V
 
T

Thomas J. Gritzan

If I have a function returning int, then I am free to ignore that
return value. For instance:

int fun(void);
x = fun(); // valid
fun(); // valid

If I want the former form to be invalid, I can instead make the
function of type void:

void fun(void);
x = fun(); // invalid
fun(); // valid

I don't know a way to do this at compile time, but you could return an
object, that will throw an exception or assert() in the destructor, if
you didn't call a specific get() function on it.

But the problem below is not something where I would use this.
The reason I would like such a thing is this.
[...]

In short, you want a 'lazy repaint' for your GUI windows.

The usual way is, AFAIK, to have a 'needs repaint' flag (sometimes
called 'is_dirty') in all your windows/widgets, which is set to true, if
this window needs to repaint itself.
Your GUI message queue then processes all its messages, and when there
are no more messages, that is, when the application is idle, it repaints
all windows which have this flag set.
 
B

Balog Pal

The reason I would like such a thing is this. I am writing a program ....
present the routine handling the change of file name will repaint the
note if necessary. But if the user makes both changes then this can
result in the note being repainted twice, the first time incorrectly
as it has not yet taken all the changes into account.

Does not sound so bad. Though you must use some interesting system. I.e. on
windows all you do is 'invalidate' the window or an area. Paint will be
called eventually, after all the things done, and will figure out what to
draw from the latest state. So multiple invalidates still result in a single
paint without anyone's work. Unless certainly the repaint is forced by
UpdateWindow() or alike, that is not suggested.
So I am
considering moving the repaint up into the edit properties routine, so
that there will be one repaint afterwards if either or both of the
subroutines say it is necessary. Since the subroutines thus lose
direct control over whether the repaint happens, I would like to
ensure that their return value (indicating whether it is required) is
not ignored to make it harder for me to mess this up.

This sounds like a bad design. If the user calls 'ChangeText()' or
ChangePicture(), he wants an action. Not a query whether he shall paint or
not. I'd make them void functions.
And if repaint is needed in a different way than suggested above, the class
itself can handle a 'dirty' flag that is set by any function calling for a
repaint. Then you can issue an Update() working from those flags (possibly
doing nothing). With some luck you can issu that autmaticly somewhere, if
not, you can tell the user that it's obligatory at some points -- though
must be called mandatorily, not forcig to twiddle with conditional logic,
etc.
 
M

Marcel Müller

Victor said:
There is no way. Even if you force the caller of the function to get
the value, what makes you think the caller is going to do anything about
the value it gets?

int unignorable fun();
...
int dummy = fun();
// go on with our processing without paying attention to 'dummy'

This will raise a warning about dummy on many platforms.


Marcel
 
M

Marcel Müller

Hi!

But supose I have a function where I don't want the return value to be
ignored. Is there any way I can do this? For instance:

unignorable int fun(void);
x = fun(); // valid
fun(); // invalid

void fun(int unignorable& retval);
fun(x);
fun(); // invalid

[...]
showing the text or vice versa, it again will need repainting. At
present the routine handling the change of file name will repaint the
note if necessary. But if the user makes both changes then this can
result in the note being repainted twice, the first time incorrectly
as it has not yet taken all the changes into account.

Add
bool repaint;
to your object and post a request to your message queue, every time the
repaint flag turns to true. The request handler checks and clears
repaint. This will merge the repaint in most cases. In an multi-threaded
application you may do this with atomic instructions.
Of course, you have to take care of the objects lifetime when doing this
kind of asynchronous painting. But GUI applications usually have to do
this anyway.

So I am
considering moving the repaint up into the edit properties routine, so
that there will be one repaint afterwards if either or both of the
subroutines say it is necessary.

Bad idea to intermix the presentation layer with the controller logic.


Marcel
 
B

Bo Persson

Victor said:
Yes, I am sure. And there is no way around this of course...

So the creative programmer will then add a "utility" function

void ignore_return(int)
{ }

to take care of the unignorable

ignore_return(fun());

So, there! :)


Bo Persson
 
G

gw7rib

Thanks to all for your replies.

(e-mail address removed) wrote:
void fun(int unignorable& retval);
fun(x);
fun(); // invalid

Thanks for that - I'm not sure it's what I want here, but it is a neat
trick I will bear in mind for the future.
Add
   bool repaint;
to your object and post a request to your message queue, every time the
repaint flag turns to true. The request handler checks and clears
repaint. This will merge the repaint in most cases. In an multi-threaded
application you may do this with atomic instructions.
Of course, you have to take care of the objects lifetime when doing this
kind of asynchronous painting. But GUI applications usually have to do
this anyway.

One problem with this is that, if the user changes the text of a note
(by associating it with a different file) but the note is showing an
image instead of its text, then the note doesn't need updating if the
image is still the same. I think all the solutions offered here have
that problem.

I may be getting worked up unduly here, as the note can tell if it's
showing an image or not, and the fact that the user may have just
changed to showing text from an image and that this value has not been
set yet so it thinks the fact the text has been changed doesn't affect
it when really it does, is not a problem because if you change from an
image to text then that in itself will require a repaint. But no-one's
going to bother to read the whole of that sentence. :)

Bad idea to intermix the presentation layer with the controller logic.

Yes - that is partly why I was asking in the first place instead of
just getting on and doing it. If it's any consolation, this is a
program I am writing on my own for a hobby, it's not being produced by
a team and is unlikely to be unleashed on the wider world.
 
B

Bart van Ingen Schenau

One problem with this is that, if the user changes the text of a note
(by associating it with a different file) but the note is showing an
image instead of its text, then the note doesn't need updating if the
image is still the same. I think all the solutions offered here have
that problem.

As you say below, the note itself is aware of the content that is
visible. Therefor, the note can decide if this change to the content
or the state affects the visible content.
If and only if the visible content is affected, the repaint flag
should be set.

When handling the REPAINT message, you check the repaint flag. If that
flag is not set, you simply do nothing. This solves the problem of
having multiple updates that all set the repaint flag and issue a
REPAINT message (which should go hand in hand),
I may be getting worked up unduly here, as the note can tell if it's
showing an image or not, and the fact that the user may have just
changed to showing text from an image and that this value has not been
set yet so it thinks the fact the text has been changed doesn't affect
it when really it does, is not a problem because if you change from an
image to text then that in itself will require a repaint. But no-one's
going to bother to read the whole of that sentence. :)

Actually, I did bother to read that sentence. :)
And I have a few comments on it.
First, the internal state of the object should always reflect the
visible state *just after the next repaint* (where the next repaint
could have been ordered by the windowing system because (part of) the
window was uncovered).
Secondly, what you say is correct, because the actions of changing the
associated text(file) and selecting to display text instead of an
image could be done in either order. The net effect of changing the
order should not differ (at most, you could have an additional,
ignored, REPAINT message).

Bart v Ingen Schenau
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,610
Members
45,254
Latest member
Top Crypto TwitterChannel

Latest Threads

Top