[Issue 8185] Pure functions and pointers
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Mon Jun 4 00:52:49 PDT 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8185
--- Comment #20 from Denis Shelomovskij <verylonglogin.reg at gmail.com> 2012-06-04 11:54:40 MSD ---
(In reply to comment #19)
> I honestly don't understand why much in the way of examples are needed.
OK. I have written some examples. Are they too obvious to not be in docs?
Honestly, I'll be amazed if most of D programmers have thought about most of
that cases.
Examples:
pure functions (not sure if @system only or @safe too) in D are guaranteed to
be pure only if used according to it's documentation. There is no guarantees in
other case.
---
/// b argument have to be true or result will depend on global state
size_t f(size_t i, bool b) pure; // strongly pure
void main()
{
size_t i1 = f(1, false); // can depend on global state
size_t i2 = f(1, false); // f is free to produce different result here
// And if second f call is optimized out using i2 = i1,
// (because f is strongly pure) a program will behave
// differently in release mode so be careful.
}
---
For @system pure functions, it's your responsibility to pass correct arguments
to functions. These functions (even strongly pure) can be impure for
"incorrect" arguments and even results in "undefined behavior".
---
extern (C) size_t strlen(in char* s) nothrow pure; // strongly pure
/// cstr must be zero-ended
size_t myStrlen(in char[] cstr) pure // strongly pure
{
return strlen(cstr.ptr);
}
void main()
{
char[3] str = "abc";
// str isn't zero-ended so myStrlen call
// results in undefined behavior.
size_t l1 = myStrlen(str);
size_t l2 = myStrlen(str); // can give different result
}
---
@system strongly pure functions often can't be optimized out:
---
extern (C) size_t strlen(in char* s) nothrow pure; // strongly pure
void f(in char* cstr, int* n) pure
{
// strlen have to be executed every iteration,
// because compiler doesn't know if n is
// connected with cstr someway
for(size_t i = 0; i < strlen(cstr); ++i)
{
*n += cstr[i];
}
}
---
Same apply even if these functions hasn't pointers/arrays in it's signature:
---
size_t f(size_t) nothrow pure; // strongly pure
void g(size_t i1, ref size_t i2) pure
{
// f have to be executed every iteration,
// because compiler doesn't know if i1 is
// connected with i2 someway (f can expect
// that it's argument is an address of i2)
for(size_t i = 0; i < f(i1); ++i)
{
i2 *= 3;
}
}
---
One has to carefully watch if a function is strongly pure by it's signature
(the compiler is guaranteed to determine function purity type by it's signature
only to prevent different behavior between cases with/without a signature):
---
void f(size_t x) pure // strongly pure, can't have side effects
{
*cast(int*) x = 5; // undefined behavior
}
__gshared int tmp;
void g(size_t x, ref int dummy = tmp) pure // weakly pure, can have side
effects
{
*cast(int*) x = 5; // correct
}
---
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list