0

I'm testing some code for some of my students who are taking an introductory course in C++. I'd like to test whether or not some of their methods accept arguments that aren't changed as const references but other than writing a script that would parse the text in their code I can't really think of any clever way to check this.

I thought of trying to pass an Rvalue to their method, if they only accept by reference the code won't compile but this doesn't stop them from receiving their arguments simply by value.

Thanks!

crommy
  • 433
  • 1
  • 4
  • 12
  • 4
    if you cannot tell the difference why make it a requirement? Please dont put requirements on students for no good reason – 463035818_is_not_an_ai Jun 22 '20 at 07:49
  • I mean we simply asked them to implement their code that way, and its good practice to teach them to pass arguments by reference, and to keep them as const if they don't intend to change these arguments. – crommy Jun 22 '20 at 07:51
  • 1
    Make the value non-copy/movable then they can only accept by reference – Alan Birtles Jun 22 '20 at 07:52
  • 2
    Require peer reviews from rotating cohorts of fellow students, where one of the review criteria is const-correctness. Spot check these to make sure the peer reviews are catching what you expect. Since the class is teaching coding style it seems a natural extension to teach something like peer review as well. Add in fault tree analysis if you're feeling squirrely ️ – JohnFilleau Jun 22 '20 at 07:52
  • @JohnFilleau And extra marks for number of good reviews – Ardent Coder Jun 22 '20 at 07:54
  • Sadly I'm not in a position where I can ask them to do this, their grade is mostly done by automatic testing and then the TAs review about 20% of the students' code. – crommy Jun 22 '20 at 07:54
  • can you show an example? What type is the parameter? – 463035818_is_not_an_ai Jun 22 '20 at 07:56
  • 1
    What position are you in then? I realize you asked for one thing and I suggested another, which probably made you feel the same way most students on here feel when we tell them that should use `std::vector` instead of decaying pointers. – JohnFilleau Jun 22 '20 at 07:57
  • You and the class don't exist in a vacuum, and the class isn't made of stone. Everything can be changed if the will is there. If it's too late in the semester to change the grading criteria, you could offer some nominal amount of extra credit for good peer reviews with a well defined coding style document. This would of course be in addition to whatever automated method you come up with :) – JohnFilleau Jun 22 '20 at 07:57
  • I'm one of the TAs in the course, and I do like your idea, but I don't think the professors would care to try it. and yes it's likely to late to go around asking to change the grading criteria :(. So i'd like to find a way to automate this if possible, if not then only the 20% of students whose code we'll review will have this graded. – crommy Jun 22 '20 at 08:00
  • @AlanBirtles So that's a pretty good idea, except that the class cannot be non-movable or non-copyable.. and I'm not sure how it would be possible to do that without changing the class itself. – crommy Jun 22 '20 at 08:04
  • Is it possible to review 20% of (each student's code) instead of (20% of each student)'s code? When I used to TA it wasn't possible to give every assignment tough scrutiny. I scanned through all student's assignments quickly, and if something looked weird then I'd give that assignment a little more attention. – JohnFilleau Jun 22 '20 at 08:05
  • what is "the class"? Please provide a [mcve] – 463035818_is_not_an_ai Jun 22 '20 at 08:05
  • 1
    Can you give a few examples of the types of functions/classes that students are required to write? Do you give them an interface and they have to implement those functions (and only those) or do you give them freedom to implement what they need? Because if it's the latter, then any automated system that identifies non-const references or copies would still need human scrutiny to determine if it makes sense. Sometimes a copy is the correct method. – JohnFilleau Jun 22 '20 at 08:07
  • Some automated grading systems do performance measurements against test inputs. If you use suitably large inputs, then copy parameters would show up as an extra cost. – JohnFilleau Jun 22 '20 at 08:10
  • Are they all using the same IDE/compiler? I didn't find any obvious compiler options that check for const correctness, but it seems to be something that static checkers have tried to do with some level of success. I don't have a lot of experience with it though https://devblogs.microsoft.com/cppblog/check-for-const-correctness-with-the-c-core-guidelines-checker/ – JohnFilleau Jun 22 '20 at 08:11
  • @JohnFilleau The best I can do is probably describe the class. As the instructions aren't in English and I wouldn't want one of the students to possibly come across our implemenation. But the basic idea is that they need to implement a Matrix class. The class has: A constructor which receives two integers for the dimensions of the matrix A copy constructor A destructor operator= overloading and a bunch of other operators such as * , + , += , << , >> , [] etc. And I'd like to make sure that for most of these operators they are passing the right hand argument as const reference. – crommy Jun 22 '20 at 08:12
  • 1
    then why non-copyable is not an option? You can inherit from the class to make it non-copyable, call the operator, check if it compiles. – 463035818_is_not_an_ai Jun 22 '20 at 08:14
  • @idclev463035818 I like that idea a lot! thanks :)! – crommy Jun 22 '20 at 08:16
  • to make the question answerable you should add an example. As it stands it leaves out too many details. For example checking `Foo::some_operator(const Bar&)` would ask for a slightly different approach (make `Bar` non copyable) – 463035818_is_not_an_ai Jun 22 '20 at 08:17
  • @idclev463035818 so for the most part they only pass Foo objects so your idea should work. – crommy Jun 22 '20 at 08:19
  • https://stackoverflow.com/questions/9065081/how-do-i-get-the-argument-types-of-a-function-pointer-in-a-variadic-template-cla/9065203#9065203 function traits were the solution – crommy Jun 22 '20 at 09:23

1 Answers1

1

Your drivers to test student class might check lot of stuff:

  • behavior with regular tests.

  • constness by using intermediate const reference:

    Matrix Test_Const_Add(const Matrix& lhs, const Matrix& rhs)
    {
        return lhs + rhs;
    }
    
  • if class to test is template, you might use instrumentalised (to count methods called) or specific classes (non-copyable, not default constructible, ...)

  • method/function signatures by introspection:

    • function traits for non-overloaded/non templated functions.

    • assignation to member/function pointer

      float (Matrix::*at)(std::size_t, std::size_t) const = &Matrix::at;
      float& (Matrix::*at)(std::size_t, std::size_t) = &Matrix::at;
      
    • you might write tools (with LibTooling for example) to check specific stuff too.

    Care with instrospection though, as there might be several valid ways to write the code (overloads or default argument for example might "break" function trait).

Jarod42
  • 203,559
  • 14
  • 181
  • 302