2

In Haskell there is a constant called undefined that you can use to declare a function without defining it (i.e. a function prototype with an empty body) as with squarein

square :: Int -> Int   -- declaration
square = undefined     -- empty definition

main = putStrLn.show.square $ 3

This is tremendously useful to defer the work on square and focus on getting the main function right first, because the Haskell compiler makes sure that the whole file compiles as if square was defined.

The C++ equivalent is

#import <iostream>
int square(int x){
  //TODO incomplete
  return 0;
}

int main() {
  std::cout << square(3);
}

My intention is to invoke a compiler like clang++ as a typechecker for main alone and work on square later. Imagine that square really is one of many not-yet-defined complex functions that return a complex data structure with a non-trivial constructor. I would have to write a lot of code to create returnable objects just to get the functions to compile.

Is there something quick-and-dirty in C++ similar to undefined?

manews
  • 340
  • 2
  • 12
  • 2
    The linker is a step after compilation. Your code has passed the compiler's type checking already when you get that error. – Mat Nov 21 '17 at 12:05
  • 4
    Is there something you want to achieve here as this is a trivial example and your real world case can probably be solved without the need for this – EdChum Nov 21 '17 at 12:06
  • A workaround is to compile a "mock" file where minimum functions are defined (std::cout/exception/assert). You can put all the undefined functions there and remove while implementing. Not as quick as the "undefined", but a bit more secure by not crashing unexpectedly. – stefaanv Nov 21 '17 at 12:22
  • 1
    I don't really see the use for this, you could just give it an empty definition for the time being, but if you want similar behavior (e.g. a crash), you could use a macro to define something like this: `#define UNDEFINED{_ASSERT(0)}`, and then use that after your function declaration, but as @EdChum mentioned, there is probably a better way to fix your actual problem – xEric_xD Nov 21 '17 at 12:22
  • `undefined` is not something like a null pointer. One can implement `undefined = undefined`. So it is bascially a function that maps to itself. – Willem Van Onsem Nov 21 '17 at 12:37
  • 4
    `undefined` is not that useful with strict semantics. If you just want to avoid defining a function, give it a `{ throw "undefined"; }` body. – molbdnilo Nov 21 '17 at 12:55
  • 1
    @xEric_xD one use for `undefined` is that the compiler will tell you what type it expects where you've used `undefined`, this is often very useful in calls like `someGenericLibraryFn (someAbstractHelper undefined) 42` where the type signatures of the functions might be a bit long and you want to just see *that one part* of the type signature. I don't know if @mahene was hoping to get that feature from C++ though … – unhammer Nov 22 '17 at 08:10
  • @unhammer that would be a nice plus, but is not my intention. I just want a "placeholder that will crash the program if you try to actually call it, but which compiles correctly and will be type-checked" (see Davislor). – manews Nov 23 '17 at 20:50

3 Answers3

0

Thank you @molbdnilo. Using throw is concise and works perfectly:

int square(int x) {
  throw("undefined");
}
leftaroundabout
  • 117,950
  • 5
  • 174
  • 319
manews
  • 340
  • 2
  • 12
0

You can also use assert as following:

int square(int x) 
{
  assert(0);
}

This has the advantage that it can't be caught and will always fail. This will protect you better in case you forget to implement the function.

OriBS
  • 722
  • 5
  • 9
  • Uncatchability and protection against forgetting are two important points i totally missed. Thanks. In order to distinguish that assert from other "normal" asserts i [found out](https://stackoverflow.com/a/3692961/4936725) that you can annotate an assert as in assert(0&&"undefined"); – manews Nov 23 '17 at 20:25
  • But i don't like that it's a C macro that appears to be disabled in release builds. – manews Nov 23 '17 at 20:34
0

C++ has pure virtual functions, for use in abstract base classes.

class foo {
  virtual void bar() = 0;
};

The function foo::bar() cannot be called, and indeed a foo object cannot even be created, but it can be overridden in a derived class of foo. You can, however, give a definition for it that derived classes inherit by default.

Another thing in C++ that’s somewhat similar to undefined is an uninitialized function pointer. A safer, more modern solution might be a lambda expression or static stub function that aborts the program.

The meaning of undefined in actual use is something like: a placeholder that will crash the program if you try to actually call it, but which compiles correctly and will be type-checked. For individual object files, declaring an extern prototype for a function that isn’t defined anywhere will do the job. If you’re linking the whole program, there has to be some kind of definition (although function pointers can get around that, at the cost of safety), but it can be a stub.

Davislor
  • 14,674
  • 2
  • 34
  • 49