fast_io icon indicating copy to clipboard operation
fast_io copied to clipboard

mark gnu::pure to some const method

Open SekaiArendelle opened this issue 2 months ago • 14 comments

  • which help to some static analysis

SekaiArendelle avatar Nov 03 '25 01:11 SekaiArendelle

are you sure this works? list root can change, it would just produce wrong results

trcrsired avatar Nov 03 '25 02:11 trcrsired

apologizing for misunderstanding, gnu::pure should be the right one.

SekaiArendelle avatar Nov 03 '25 15:11 SekaiArendelle

@trcrsired plz review again

SekaiArendelle avatar Nov 03 '25 15:11 SekaiArendelle

it is not pure either. allocation is not pure

trcrsired avatar Nov 03 '25 16:11 trcrsired

this PR is not correct. or i should say fundamentally wrong.

trcrsired avatar Nov 03 '25 16:11 trcrsired

pure function means:

y=f(x)

Any x must produce the same y. Here it is clearly not the case.

trcrsired avatar Nov 03 '25 16:11 trcrsired

Cause C++ is not a functional programming language, gnu::pure should mean

  1. the output only rely on the input parameter (✓ this pointer)
  2. no side effect occurred.

SekaiArendelle avatar Nov 04 '25 05:11 SekaiArendelle

how? malloc is not deterministic and it affects on pointer

trcrsired avatar Nov 04 '25 06:11 trcrsired

Why empty() and size() contains side effects? They did not edit anything except generating the output.

SekaiArendelle avatar Nov 04 '25 08:11 SekaiArendelle

Why you consider bool empty(Class const*) and size_t size(Container const*) aren't pure function?

SekaiArendelle avatar Nov 04 '25 08:11 SekaiArendelle

Basically, C++ is not a functional programming language and one key reason is that variables can be mutable, which can lead to things like:

int plus(int a) {
  return a+1;
}
int main() {
  int a{};
  a = plus(a);
  plus(a); // same variable but different result
}

Anyway, pure function for C++ can be explained as given the same STATUS (not the same variable) always produces same result.

With above concept, size and empty are definitely pure, without side effect.

int main() {
  fast_io::string str{};
  str.size(); // no side effect
  str.append("text"); // status changed
  str.size(); // like above example, same variable but not same status, is actually different input for pure function
}

SekaiArendelle avatar Nov 04 '25 08:11 SekaiArendelle

@trcrsired when can this pr be merged?

SekaiArendelle avatar Nov 06 '25 01:11 SekaiArendelle

Can you go LLVM and ask LLVM folks on whether it is correct to add pure here first? thanks

trcrsired avatar Nov 06 '25 02:11 trcrsired

Hi, I have investigated lots of stuff and I'm pretty ensure it's correct.

See GCC Document: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute

However, the caller may safely change the contents of the array between successive calls to the function (doing so disables the optimization). The restriction also applies to member objects referenced by the this pointer in C++ non-static member functions.

See also: https://clang.llvm.org/docs/AttributeReference.html#pure Bad news! Clang does not document anything other than the title ) :

To avoid (potential) off-topic discuss on llvm discord/issue, I asked this question to ykiko&Kimiv2&Another C++ community on discord, and the answer is yes.

My final prove is https://github.com/llvm/llvm-project/blob/3a8f6979cef26ceb5ef5c6b8dba1fc1fd770c44c/clang/lib/AST/Expr.cpp#L3750 of its influence on side effect.

Is above enough?

SekaiArendelle avatar Nov 07 '25 09:11 SekaiArendelle