Talk:Assertion (software development)
This article is rated Start-class on Wikipedia's content assessment scale. It is of interest to the following WikiProjects: | |||||||||||
|
Hoare paper
[edit]I have noticed you quote Hoare paper and claim you use the same syntax as the original paper, but that is in fact not true at all, I suspect people have not read the paper at all. The modern Hoare tripple notation is the one used on here, that is {P} Q {R} and not like the paper which says P {Q} R. —Preceding unsigned comment added by 79.72.191.93 (talk) 11:38, 19 March 2010 (UTC)
This is David Gries. I am going to change the definition of assertion to include its more general definition: a true-false statement placed in a program (often as a comment) to indicate that that true-false statement is true at thyat place. This word is used in a discussion of the Hoare triple in this general sense (and has a link to the assertion definition), and it has been used this way since 1969. This will take me a bit of time since I am new to editing Wiki pages and I want to do it right, so please hold off on changing anything until I finish it.
Thanks, DavidGries 02:43, 2 January 2007 (UTC)
Why not assertion? I am sure the name of functions is typically assert but the functionality should be called assertion. I thought someone moved to assertion but that was moved back? -- Taku 23:11 26 May 2003 (UTC)
- The operation is called assertion checking; a test which performs it is called an assertion. Calling it an "assert", as if that were a noun, is not particularly literate. It is as if someone who had learned about the for keyword in C started calling the writing of loops "foring" .... --FOo 06:19, 6 Dec 2003 (UTC)
Inaccuracy
[edit]- an assertion is a programming language construct which immediately aborts program execution if a certain condition or expression is false
This is often the case, but not always: writing a warning and continuing, or simply ignoring the assertion are possible reactions to failed assertions at runtime. Often one is not really all that interested in assertions at runtime, but regard them as a piece of information for compilers or program analysers. ---- Charles Stewart 14:47, 21 Sep 2004 (UTC)
- Fixed in the latest version of the article. Neilc 23:54, 29 Mar 2005 (UTC)
Use of assertions
[edit]The article states:
- For example, following the dynamic allocation of memory in a programming language such as C, a pointer may be checked to ensure that it is not null before proceeding. Without such an assertion, a reference may occur later that would cause an error.
This is a bad idea. malloc
may fail when the system is OOM, under heavy load, or really at the whim of the implementator of the C standard library. A well-written program should not hit an assertion failure when this occurs — it should recover from the error condition, to the extent that is possible. If error recovery isn't possible, the program can emit an error message and exit. This is different from an assertion failure, which indicates that a logically-impossible situation was reached (i.e. a likely logic bug in the program). This isn't the case: OOM is certainly a logically-possible situation.
Generally speaking, there is little point checking that a pointer is not NULL
. If there were some canonical way in C to ask "is this pointer valid?" that would be one thing — but there isn't. A non-NULL pointer can easily be invalid, so the check is incomplete. Furthermore, dereferencing a NULL pointer leads to an immediate access violation on any modern modern I'm aware of — in other words, the effect of stopping the program immediately can easily be achieved without needing an assertion. Neilc 17:23, 27 Mar 2005 (UTC)
- I don't necessarily concur with you in every bit, but I can certainly see your points. Do you know any better example that makes sense without one knowing context? -- Taku 18:17, Mar 27, 2005 (UTC)
- After looking around a bit, I think an example from the Sun page on assertions in Java is pretty good:
if (i % 3 == 0) { ... } else if (i % 3 == 1) { ... } else { assert i % 3 == 2 : i; ... }
- Note, incidentally, that the assertion in the above example may fail if i is negative, as the % operator is not a true modulus operator, but computes the remainder, which may be negative.
- so the assertion documents the assumption that
i
is non-negative. Once we resolve the dispute about which version of the page is better, I'll add an example similar to the above. Neilc 02:39, 28 Mar 2005 (UTC)
- so the assertion documents the assumption that
- I suggest that waiting till the pointer is dereferenced is definitely inferior to asserting that the pointer is not null. The assertion gives a clearer indication of the true point of failure. Of course higher quality code needs error-handling, but in some circumstances the assertion may be more cost-effective, e.g. when writing a one-off tool for ones own use. PJTraill 01:31, 12 December 2005 (UTC)
Good practice
[edit]Reverting a major change to a page without discussion isn't nice, and isn't consistent with Wikiquette. Although I think my changes were definitely an improvement, I'll argue for them here rather than childishly re-reverting the page.
Why should we not talk about what is good practice? Simply because it is a source over which people can disagree is not a reason not to discuss it — if that were grounds for not including content, we wouldn't have articles on many, many subjects. If there are alternative points of view about the proper use of assertions, we can discuss those as well. Talking about how one should use assertions is pretty important to defining what an assertion is — an assertion is a programming tool, and providing a detailed discussion of a tool entails explaining when the tool is appropriate, and when it is inappropriate. Neilc 02:32, 28 Mar 2005 (UTC)
- I am sorry if I was not careful in reverting your edit. Since you really altered the article in the fundamental way, I can't do anything but revert. But I hope you do realize that you also remove some points, which is not nice either. Since your new version in the page history anyway, we can work on it together. (Though I might not have time after Easter) If you think what I did is childish, (though I think that's just usual procedure in wikipedia), then so is yours maybe.
Anyway, to get to the point, my point is not we should avoid the matters that are the source of dispute. And I don't disagree that we should mention how to make points on what. Indeed this old version says it is a bad practice to use assertion to do error checking. What I am saying is that we have to say this before saying why some code has assertions and some don't. That is, we are giving the reasons why assertions are often removed.
- (1) Assertions may slow the program.
- (2) Since assertions are usually not used for error checking, it is usually expected that the removal of them does not change the semantics.
The mention of how per se is ok, but the problem is the way it is said. Now let's go back to your version. How about this one:
- Using assertions is often considered good practice.
This may be true or may be not. But what is the point of saying this? Again saying this per se is not a problem at all. In fact, I like sentences like "Assertions also simplify debugging: if an assertion no longer holds, the programmer would like to be informed immediately." So we can say like a number of programmers find the use of assertions helpful, and indeed some languages like Java have built-in assertion mechanism. In short, why do we concentrate on how programmers use assertions (e.g., simplifying debugging) instead of how they should use (e.g., using assertions is good.) Your version smells like a book about how to write good code, and this is usually a bad sign.
-- Taku 03:15, Mar 28, 2005 (UTC)
- Just to be clear, I was saying it would have been childish of me to re-revert the page without discussion, not that the original revert was childish.
- I think we should talk about both what an assertion is and how assertions are used, since the latter is pretty important to having a clear understanding of the former. If we're going to describe how assertions are used, it only makes sense to me to differentiate between uses of assertions that are considered "good practice", and those that are not. Anyway, I've modified the article to preach less about what the user should do, and to talk more about the difference between assertions and other forms of handling exceptional situations. Let me know if the new version is ok. Neilc 07:17, 28 Mar 2005 (UTC)
I went ahead to rewrite the article to make points instead of replying to you here. (By the way by doing this I never mean to be sarcastic.) If my writing makes sense, this version tells how assertions help programmers, and how they are typically implemented. Hence, the article is divided into two sections. I think we have some idea about assertions, but we just take a different approach to tell the idea. I think the way this version is written is the way articles in wikipedia are written if not the way of the textbook or typical programming books. Since I rewrote the article to make points, please do not hesitate to rewrite it or even revert it. I hope you can see what I am trying to say. -- Taku 17:07, Mar 28, 2005 (UTC)
- The revised version is fine with me in principle. It needs a fair bit of copy-editing — I'll do that when I get a chance... Neilc 02:27, 29 Mar 2005 (UTC)
- I am sorry about bad English (more like Engrish). But thank to you and others, the current version, I think, is quite good. The third section (comparison with error handling) simply says it is a bad idea to use assertions for error handling. And I think this is a good idea since we are not talking like this is how you should use assertions, and how you should implement them. -- Taku 17:18, Mar 29, 2005 (UTC)
Handling assertion failure
[edit]The following has been removed:
- In some cases, assertions may be configured so that when they fail they do not terminate the program, but leave a log entry. This is often the case when the program involves access to networks or intricate caching or concurrent executions. In those cases, it is often difficult to reproduce the same execution path, thus the assertions failure.
Is it not true? I myself did see this kind of implementation before. -- Taku 04:14, Mar 30, 2005 (UTC)
- The current version of the article talks about the various ways of handling assertion failure (ignore it, halt program, print information about the error, etc.), so I think the content of the first sentence is still in the article. The second and third sentences don't make sense to me — I'm not sure why a concurrent program would be more or less likely to dump core when an assertion failure occurs. Part of the point of halting the program immediately (in languages like C) is getting a stack trace, which can be particularly useful in concurrent programs. If you want to discuss how different kinds of programs handle assertion failure in different ways (in general), that's fine with me -- I'm just not sure how broadly you can generalize here. Neilc 07:04, 30 Mar 2005 (UTC)
Comprehensibility
[edit]- The article's content is rated an age +16 comprehension level by Kristan Wifler
maybe someone could make a -15 sibling page?
PJTraill 21:35, 30 April 2006 (UTC) Why? Are there many programmers with mental age < 16? If this article is hard to understand without justification by e.g. greater precision, it should be clarified. A version in the simple-english Wikipedia could also be useful.
prop merge from Can't happen
[edit]I'm not even sure can't happen is a concept, instead of just an often-repeated comment (often accompanied by assert(0)). In any case, I belive discussion of it belongs here, if any. Ripper234 17:53, 2 April 2006 (UTC)
PJTraill 19:52, 2 April 2006 (UTC) I've not heard the expression myself, but I reckon it covers the same ground. I think that "Can't happen" should just redirect here. The entire "Can't happen" article consists of these two paragraphs:
- In computer programming, "can't happen" refers to code often inserted by a programmer in order to report if there is a fault in the program and the "can't happen" does happen.
- PJTraill 19:52, 2 April 2006 (UTC) OK, let's mention that somewhere
- "Assertions" are a variation on this — code that "asserts" that a situation must be true and reports if it is not so. For example, in a medical application a database must never link a treatment to the wrong patient, as this could have serious effects. To be certain that an unforeseen situation will never produce an undetected error, a programmer may separately record the Patient ID on every treatment, and on recalling it check that the treatment has that Patient ID, and if not so then suppress the display of the offending record labelling it as "unrecallable". This is "can't happen" code in one sense, but "shouldn't happen" code in another sense and can be used to ensure very high reliability.
- PJTraill 19:52, 2 April 2006 (UTC) We don't need any of this. The example is actually not bad, if rather specific, but I don't like the "unrecallable" idea. It is fortunately irrelevant, but it illustrates a dishonest or misleading interface – you should say there is an error in the DB. The last sentence seems dubious as far as I understand it: assertions do not of themselves ensure that code is reliable (unless verified at compile-time), they just help the programmer to make it reliable by improving the effectiveness of testing.
- Please do merge. "Can't happen" sounds silly and unscientific, especially when an equivalent widely used term (assertion) is available. Wouter Lievens 12:11, 28 April 2006 (UTC)
- The trouble is that the can't happen article has been redirected here, but the phrase "can't happen" doesn't appear anywhere in this article, leaving the reader wondering exactly how to connect what they've clicked on and where they've ended up. I think either that redirect needs to be deleted or something about "can't happen" needs to go in this article. In any case, people more knowledgeable about this than me should go through the articles that link to can't happen sorting out the links and the wording to avoid confusion. Beorhtwulf (talk) 17:01, 28 February 2011 (UTC)
- I have no prior knowledge about the concept of assertion, or what the term "can't happen" means in this context. The link I clicked in the brownout article for the term "can't happen" led me here. After reading this article I have no clue what the brownout article meant by "can't happen." In short I agree that either the redirect should be eliminated or the "can't happen" term should be defined in some way on this page. Failing either of those we're left with a situation where the wikipedia entry doesn't define a term that re-directs to it. The only way I see that a person could glean any information about "can't happen" from this article is if they had prior knowledge of it that allowed them to see whatever parallel may or may not be here(personally, as far as I can tell there aren't any).AaronMP84 (talk) 23:30, 5 January 2013 (UTC)
I've restored this as an article. As AaronMP84 says, we can't have it redirecting here and then not say something here. The choices are (1) merge it properly, then it can go back to being a dab page, (2) take it to AFD and get it deleted, in which case it will end up as a redirect to Don't-care term, or (3) improve the article or just leave it as it is. SpinningSpark 23:39, 16 December 2022 (UTC)
The material on Hoare triples in the introductory section strikes me as far to long, detailed, and one-sided. I reckon it belongs later, perhaps in a section on theory. PJTraill 00:59, 19 January 2007 (UTC)
malloc example
[edit]The malloc() example (illustrating incorrect use of assertions) is a bad one. On modern operating systems with memory overcommit, running out of memory will not cause malloc() to return NULL. Instead, it will usually result in a segmentation fault in some random part of the code, not necessarily anywhere near the malloc() call. Running out of address space, on the other hand, will cause malloc() to return NULL, but it is usually the result of a programming error. This is especially true on a 64-bit platform, where address space size exceeds actual memory size by several orders of magnitude.
Combine those facts with the difficulty of gracefully recovering from an allocation failure, and you will see that it often makes sense to treat malloc() as if it can never return NULL. There isn't much point in sticking an assertion in there, though, since the simple act of using the NULL pointer will terminate the program much like an assertion failure would (and will often leave a more useful stack trace).
DES (talk) 22:58, 21 January 2008 (UTC)
Not everything is a modern OS – lots of C code is written for embedded systems without virtual memory stuff.
I'm not happy about that part of the article for other reasons – it starts by saying that it's "unwise" to use assertions for things which you believe can happen, but then slides over into the malloc() example, and it isn't clear that the article believes this is "unwise".
By the way, a long, recent thread on USENET's comp.lang.c++.moderated shows how much programmers disagree about the meaning and proper usage of assertions (in C++). See Message-ID: <10ce7fc0-d6e1-4801-9f7c-9ed181fe1af5@a1g2000hsb.googlegroups.com> and the rest of that thread, "assertions: does it matter that they are disabled in production?".
JöG (talk) 07:55, 4 January 2009 (UTC)
- I'd prefer another example, too. Input validation would be a better example for badly used assert() as it would allow malicious input to terminate the program. However, after input has been validated, assertions can be useful as they allows safety checks that can be easily disabled for optimal performance. Also I think in practice very few software recovers gracely from allocation failures. Even if they're handled, the internal state of the program may become dysfunctional which can easily be worse than terminating as the latter is easy to detect. --77.8.99.210 (talk) 17:56, 15 January 2011 (UTC)
Static assertions
[edit]Assertions that are checked at compile time are called static assertions. They should always be well-commented. (emphasis mine)
I don't understand that last sentence. What does commenting have to do with this? I don't see any specific reason why statically checked assertions are more deserving of comments than other assertions, or other pieces of code for that matter. Wouter Lievens (talk) 09:06, 8 May 2008 (UTC)
- Just a guess (I didn't write this, and don't fully agree with this): In C++ static assertions usually produce nearly incomprehensible compiler errors, which can reach several pages in length. Without a proper documentation that this is /intended behavior/ in this situation, a less-experienced developer might be left in a very confused state.129.69.55.52 (talk) 18:48, 29 July 2008 (UTC)
- kfsone: The original author didn't allude to them being more needy of good documentation. Runtime asserts tend to be conditionals that have code-logic, function names, etc, that can provide a coder with fairly easy roads to understanding the test being performed. Static asserts tend to be very obtuse. Why does it matter that sizeof(foo) is 4? Why should compilation of this module fail if _DEBUG is not defined? 20 years experience regularly working with/maintaining other people's code (Y2K certified MMDF, I must have been evil in a previous life) since I was a small child certainly leaves this coder with the impression that people need to have it stressed that static asserts need to be documented.
- Perhaps it's because they tend to occur in areas of code that are usually less well documented - frippery like prototypes and obscure headers; perhaps its because coders tend to think that as part of the program declaration "this will never happen" while they are less trusting of execution behavior.
- Most likely it's because when assert( strlen(p) != 0 ) breaks, it's a logic problem that we are accustomed to fixing but when some static constant suddenly begins to evaluate outside of a domain or an enum list contains too many values or an entity's sizeof() exceeds a boundary you are presented with a potentially radical design change.
- I would proffer, based solely on my years of experience, runtime asserts are usually something you will deal during initial testing with while static asserts frequently prove to be someone else's problem and they usually have some constraint that originates outside of the code itself such as a design decision or a medium constraint such as bandwidth or some very obscure performance artefact of some complex number cruncher/fancy hash algorithm/nightmare to debug. Kfsone (talk) 04:49, 12 November 2008 (UTC)
The initial C example
[edit]Is there any particular reason that the C example goes like this
x = 5;
// {x > 0}
x = x + 1;
// {x > 1}
rather than like this?
x = 5;
assert(x > 0);
x = x + 1;
assert(x > 1);
The latter is certainly clearer to any C programmer (not to mention that it can actually be checked at runtime). JöG (talk) 07:32, 4 January 2009 (UTC)
- I agree that it is a bad example, but not for the reason you state. The text preceding the example clearly mentions unchecked assertions. The example is intended to illustrate the use of source comments to document assertions in languages which lack checked assertions. However, assertions in C are not a language mechanism; assert(cond) simply expands to code that terminates the program (usually by calling abort()) if cond evaluates to 0 at run time. This means that assertions can not be checked at compile time. A good compiler will eliminate the assertion check if the condition is obviously true (as it is in this case), but it will not issue an error, or even a warning, if it is obviously false. Still, it's better than nothing... DES (talk) 14:57, 14 January 2009 (UTC)
Conflating concept and implementation
[edit]Hi Everyone,
I feel like the article conflates the concept of asserts (state, preconditions, postconditions, Design by Contract) and implementations details (specifications like POSIX assert and languages like C and C++). I think the article should make a distinction between the two.
For what its worth, I love asserts. They create self-debugging programs so I don't have to waste time under a debugger. But asserts in C and C++ are a debug facility and they should be removed in release configurations. In C and C++ you need to write a real `if` statement at runtime to enforce the conditions.
Two related discussions are Asserts considered harmful (or GMP spills its sensitive information) and Crypto++ Assertions. They provide a discussion of some of the problems in practice for C and C++. I've never seen a "Design by Contract" doc that says sensitive information, like passwords and private keys, will be breached due to a failed precondition. But that is what sometimes happens in practice in C and C++.
Jeffrey Walton (talk) 06:31, 9 November 2020 (UTC)
Assert/Verify macro example
[edit]If you are looking for an example of a statement being removed inside an assert macro due to NDEBUG (and the need for verify macro instead), then see Nettle's bug at GMP and assert() on LWN.
Here's the article's example of the assert/verify macro problem:
int *ptr; // Statement below fails if malloc() returns NULL, // but is not executed at all when compiling with -NDEBUG! assert(ptr = malloc(sizeof(int) * 10)); // use ptr: ptr isn't initialised when compiling with -NDEBUG!