[Mesa-dev] [PATCH 08/14] glsl: Add copy-constructor for ast_struct_specifier.

Chad Versace chad.versace at linux.intel.com
Wed Jul 3 15:13:34 PDT 2013


On 07/03/2013 12:03 PM, Matt Turner wrote:
> ---
>   src/glsl/ast.h | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
>
> diff --git a/src/glsl/ast.h b/src/glsl/ast.h
> index 3bb33c5..f00ef3a 100644
> --- a/src/glsl/ast.h
> +++ b/src/glsl/ast.h
> @@ -453,6 +453,18 @@ class ast_declarator_list;
>
>   class ast_struct_specifier : public ast_node {
>   public:
> +   /**
> +    * \brief Make a shallow copy of an ast_struct_specifier.
> +    *
> +    * Use only if the objects are allocated from the same context and will not
> +    * be modified. Zeros the inherited ast_node's fields.
> +    */
> +   ast_struct_specifier(const ast_struct_specifier *that):
> +      ast_node(), name(that->name), declarations(that->declarations)
> +   {
> +      /* empty */
> +   }
> +
>      ast_struct_specifier(const char *identifier,
>   			ast_declarator_list *declarator_list);
>      virtual void print(void) const;


See patch 7's review. This isn't a copy constructor. The copy constructor's
signature is T::T(const T&) where T=ast_struct_specifier.

The compiler still generates the default copy constructor, so we get this scary
behavior:

    ast_struct_specifier orig;
    ... // do stuff to orig

    // This creates the copy you want.
    ast_struct_specifier copy0(&orig);
    assert(copy0.link.next == NULL);

    // If someone accidentally writes this code, it compiles without warning,
    // but creates a buggy copy.
    ast_struct_specifier copy1(orig);
    assert(copy0.link.next == orig.link.next);

There are two ways to safely fix this patch. A C++-way that uses
references, and a way that lets people code in the C-way using pointers.

Fix 1
-----
Change the signature to `ast_struct_specifier(const ast_struct_specifier& that)`.
Then you will have defined the copy ctor, preventing the generation of the default
copy constructor. A possible unwanted side-effect, from the perspective of a C
programmer, is that we must pass the original ast_struct_specifier as a ref rather
than a pointer.

Fix 2
-----
Leave the constructor as-is in the patch. Fix the commit subject as discussed in
patch 7's review, since the patch now adds a new constructor, not a copy
constructor. Then, to prevent accidental use of the default copy constructor,
prevent it's generation by declaring it but not providing a definition.
It doesn't matter if you declare it as public or private, since it will
cause a compile-time error either way if anyone tries to use it,
but Google's and LLVM's practice is to declare it private.

Like this:

    class ast_struct_specifier: public ast_node {
       ...
    private:
       /* Prevent use of copy constructor. */
       ast_struct_specifier(const ast_struct_specifier&);
};

----

I prefer 1 because, if we're defining a ctor that looks and acts like the
copy ctor, then let's just define the copy ctor and be done with it.
However, I don't know how you're using this in future patches, so it's
your call.


More information about the mesa-dev mailing list