7

Is there a way to implement strings to work both at compile time and run time?

AFAIK for a class to be constexpr constructed it needs to have a trivial destructor. However, this proves difficult when we're dealing with strings. If the string is NOT constexpr, then it needs to deallocate memory. However, if it IS constexpr, then it is statically allocated and shouldn't be deleted, thus allowing a trivial destructor.

However, it's not possible to say "Hey, Compiler! If I'm constexpr, you don't need to destruct me!" Or is it?

It would be something like the following:

class string {
private:
    char * str;
public:
    template<std::size_t l>
    constexpr string(const char (&s)[l]) : str(&(s[0])) {}
    string(const char * s) { str = strdup(s); }
    static if (object_is_constexpr) {
        ~string() = default;
    }
    else {
        ~string() { free(str); }
    }
};

The closest I've been able to come is having two separate types, string and constexpr_string, a user-defined literal _string returning constexpr_string, and a user-defined implicit conversion from constexpr_string to string.

This isn't very nice though, as const auto s = "asdf"_string; works but const string s = "asdf"_string; does not. Additionally, a reference/pointer to a constexpr_string won't convert. Inheritance either way causes un-intuitive "gotcha"s, and doesn't resolve the first problem.

This seems like it should be possible, as long as the compiler were to TRUST the programmer that the constexpr didn't need to be destructed.

If I have a misconception let me know.

5
  • I think you're looking for strwrap from akrzemi1.wordpress.com/2011/05/11/… Commented May 2, 2012 at 16:07
  • String Literals const char (&Var)[N] are the constexpr string type. Commented May 2, 2012 at 16:28
  • 1
    You've got to love when people start using features like static if before they are approved! Commented May 2, 2012 at 16:47
  • 3
    @David: I for one would not approve a feature if people weren't already trying to use it. The technical term for such features is "useless" ;-) Commented May 2, 2012 at 16:56
  • @SteveJessop: Well, there are many rough corners with the proposals and the language, the first of which is how it interacts with two-phase lookup (which is not an issue in D). Then again, there are some proposals accepted that were not being used (consider rvalue-references), but were clearly an improvement. There is a great difference between having an implementation and use cases and it being used in SO. Also note, that was no criticism, but praise on the proposal: it is good enough for people to start using it after just hearing the concept! Commented May 2, 2012 at 18:09

2 Answers 2

11

It's not only a matter of destruction.

A constexpr operation should only call other constexpr operations and new, malloc etc... are not constexpr. Note that this is a statically checked property and does not depend on the runtime argument, so the call to such function must be absent altogether, and not merely hidden in a branch that is (supposedly) not taken.

As such, it will never be possible to get a constexpr string.

Sign up to request clarification or add additional context in comments.

10 Comments

It can't even be in a non-constexpr constructor? It seems like it should be possible to have both constexpr and non-constexpr constructors for a given type, just as it is possible to have const and non-const methods.
You can totally make a constexpr string-type, it just won't be able to handle non-constexpr strings. Just make conversion functions.
The way I see it, constexpr is a way to blur the line between compile time and run time computation. Primitive types allow this, and it seems like it should be possible to do some things to allow pointers in classes to either point to a literal or dynamically allocated memory. Functional languages have abstracted over the compile time/run time boundary for quite some time now. @Mooing Duck: conversion functions seem to break the abstraction
@RobertMason: the heap is highly runtime dependant (and stateful) and cannot be executed at compile time. Period. The best you can do is just do it at runtime at startup.
"You can totally make a constexpr string-type, it just won't be able to handle non-constexpr strings. ". That's not true at all. A non-owning runtime string class is totally feasible. Aka' stringref.
|
0

It is possible, to a certain extent, see the code example in this page. You can create constexpr conststr objects and call some operations on them, but you cannot use them as non type template parameters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.