Function to always round up to the nearest tenth

Pages: 12345
63
64
65
cout << "out : " << d << endl << endl;
if(--N > 0) main();
}


Heading for a stack overflow there !

51
52
53
int n, dot = out.find(".");
if(dot != string::npos && ((out.length() - 1 - dot) >= 2) && (round = true)) n = dot + 1 + 1; 
else n = out.length();


Was that an intended side effect? If so, things like that are hard to spot, probably not good practise - should at least document it.

This is also dangerous:
52:8: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

Too bad, your very solution does not really comply with your expectations : (


That could be construed as being a little unpleasant.
@TheIdeasMan
Have you tested my solution?

And...

(round = true)

It was done on purpose.
closed account (48T7M4Gy)
.
Last edited on
I was just pointing out some things that may not be quite right or not good practise.

With the round=true I was saying to either think of a better way to code that, or at least document that there is an intentional side effect.

Calling main is definitely wrong, and would trigger a stack overflow if it happened enough times.

The warning about comparison between unsigned and signed might be a problem depending on how a particular compiler represents signed integers (1 of 3 ways) That is why the warning is there, it could cause a problem. In my mind, if there are compiler warnings, then one isn't finished. However it is easy to fix that particular warning.

> That is why the warning is there
Can you show me the code with the warning?
> Calling main is definitely wrong, and would trigger a stack overflow if it happened enough times.
No, any recursive function can trigger a stack overflow if it happens enough times.
closed account (3h0oLyTq)
Someone was probably going on rampage and abusing their power, killing one person in the process.

To the dead person : If you wish to continue to participate in this topic, feel free to reincarnate.
Can you show me the code with the warning?


52:8: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
64:18: warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]

51
52
53
int n, dot = out.find(".");
if(dot != string::npos && ((out.length() - 1 - dot) >= 2) && (round = true)) n = dot + 1 + 1; 
else n = out.length();


The problem is n and dot are signed, std::string::npos is not. So dot needs to be std::string::size_type or std::size_t and n should be std::size_t. On line 53, mixing an int type and a call to length() or size() is a classic mistake, and is often overlooked because the warning levels were not set high enough. As I said earlier it's easy to fix. I look forward to your re-written version of those 3 lines, one that fixes the type problems and the side effect.

No, any recursive function can trigger a stack overflow if it happens enough times.


It's explicitly forbidden in the standard, in several places. I gather that it's worse than an ordinary recursive function because it copies the stack frame for all of main, as opposed to just the stack frame for an ordinary recursive function. Don't worry you were not the first to try this, and won't be the last, but it is definitely very wrong.

http://stackoverflow.com/questions/2128321/can-main-function-call-itself-in-c
Last edited on
it copies the stack frame for all of main, as opposed to just the stack frame for an ordinary recursive function.
Huh? What's that supposed to mean?

What the program does when it recursively calls main() is as relevant as what it does when it deletes an invalid pointer. Calling main() is a bug by definition of the language, and it should be fixed.
@helios

You are of course completely correct: we agree that it is a bug by definition and UB, and you are right about the relevance of what UB might do. But the program does run (the compiler is not required to report it as an error, not sure why it isn't an error) - what does it do? I had the impression it was the same as any other recursive function. With a normal recursive function the compiler puts the info it needs into a stack frame for each function call, and pushes this stack frame onto the stack. With each call to main - it's the same, but this time there is all the information associated with main (all it's local variables amongst other things), so it leads to a SO earlier. That is my understanding and what I meant with my comment.

I am sure you have been through the following in detail but here it is anyway:

https://en.wikipedia.org/wiki/Call_stack
The function main shall not be used within a program. - IS

This is not a rule with either of the clauses "no diagnostic is required" or "undefined behaviour"

1
2
3
4
5
int main()
{
    if( false ) main() ; // *** error: ISO C++ does not allow 'main' to be used by a program (clang++)
                         // *** error: ISO C++ forbids taking address of function '::main' (g++)
}

http://coliru.stacked-crooked.com/a/f8376f6494c702ba
Last edited on
So does this snippet code do anything different?

1
2
3
int N = 25;
int my_main(){if(--N) return my_main();}
int main() {my_main();}


And...
What are functions that are called before main()?
And...
What are functions that are called before main()?

Maybe create a thread with an appropriate title and ask these questions there.
@TheIdeasMan
Thanks for pointing out the warning. But unless the OP comes back, I doubt there would be no point in continuing further. I am fully aware of that my solution has some flaws, but if the OP starts to pay some genuine interest in it, I am willing to further improve the solution so that in order to best solve the OP's main problem and comply with the OP's expectations to the fullest.

@cire
Yes, it's off-topic. But I don't need to know it anyway - it's just to prove that main() is no more than that of an ordinary function, and main() is not the first function called in a program.
Last edited on
Yes, it's off-topic. But I don't need to know it anyway - it's just to prove that main() is no more than that of an ordinary function, and main() is not the first function called in the program.

I don't know what you think the latter has to do with the former, but according to the standard main is not ordinary in they way you're claiming it is.

But, hey.. keep talking out of your ass and filling the forums with misinformation and novice code while pretending you're an expert. I'm sure you're impressing yourself.
Edit: I didn't see the previous 3 posts, nor the ones after, while doing this one.

@JLBorges

Yes, we all agree one should not do that :+) Forgive me for the following, it is pedantic and purely academic; I only mention it as a means of explaining my earlier comment. I also feel somewhat trite in quoting the standard to you - of all the people :+D And it probably wasn't worth me spending time in making this reply.

But one can compile and execute the code.

I believe you have it as a compiler error because you used -pedantic-errors Crikey, you taught me to use that, and I do :+) That in itself is a lesson, and really the argument should end right there. But this time I used cpp.sh with all 3 warnings ( -pedantic not -pedantic-errors)

This part of the standard, section 1.9.5

5
A conforming implementation executing a well-formed program shall produce the same observable behavior as
one of the possible executions of the corresponding instance of the abstract machine with the same program
and the same input. However, if any such execution contains an undefined operation, this International
Standard places no requirement on the implementation executing that program with that input (not even
with regard to operations preceding the first undefined operation).


If a program shall not call main, but can be compiled with warnings, and executed, and given the above paragraph does this mean it is UB?

And this bit about the diagnostic:

1.3.25

undefined behavior
behavior for which this International Standard imposes no requirements
[ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of
behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior
ranges from ignoring the situation completely with unpredictable results, to behaving during translation or
program execution in a documented manner characteristic of the environment (with or without the issuance
of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.
— end note ]

Last edited on
closed account (48T7M4Gy)
Language!
closed account (48T7M4Gy)
Apologise cire!
@closed account 5a8Ym39o6 (560)

So does this snippet code do anything different?

i
1
2
3
nt N = 25;
int my_main(){if(--N) return my_main();}
int main() {my_main();}


The point is, if you make N a larger number, then compare your original code to this code snippet, the SO will happen much earlier with the original code.

Anyway, when are you going to finally agree that calling main is a very bad idea?
closed account (48T7M4Gy)
@cire says:
But, hey.. keep talking out of your ass and filling the forums with misinformation and novice code while pretending you're an expert. I'm sure you're impressing yourself.


This sort of disgraceful language, exaggeration and bullying will not be tolerated Cire. Stop it and apologise.
Pages: 12345