Skip to content

Can't use function pointers in C++11 code #64

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
stephenpascoe opened this issue Jan 3, 2018 · 4 comments
Closed

Can't use function pointers in C++11 code #64

stephenpascoe opened this issue Jan 3, 2018 · 4 comments

Comments

@stephenpascoe
Copy link

I can't get inline-c-cpp to compile if I use the funCtx to try and call Haskell from C++. The problem seems to be I can't specify exactly when to use the "-std=c++11" switch in Cabal.

Below is a minimal file which exposes the problem. My system is:

  • OSX El Capitan
  • stack v1.6.3, resolver: nightly-2018-01-02 (ghc 8.2.2)

src/Lib.hs

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Lib
    ( someFunc
    , someFunc2
    ) where

import qualified Language.C.Inline.Cpp as C
import Data.Monoid
import Foreign.C.Types (CDouble)

C.context $ C.cppCtx <> C.funCtx

C.include "<iostream>"


-- This snippet will only compile WITH "ghc-options: -optc-std=c++11"
-- Simulate including a header file with a C++ enum
C.verbatim "enum class MyEnum : char { OK = 0, FAIL = 1 };"

-- This function will only compile WITHOUT "ghc-options: -optc-std=c++11"
someFunc :: CDouble -> CDouble
someFunc x = let f x = x + (fromRational 42.0) in
  [C.pure| double { $fun:(double (*f)(double))($(double x)) } |]


-- This function compiles regardless of whether "ghc-options: -optc-std=c++11" is set
someFunc2 :: IO ()
someFunc2 = [C.block| void { std::cout << "Hello World!" << std::endl; } |]

package.yaml

library:
  source-dirs: src
  extra-libraries: stdc++
  ghc-options:   -optc-std=c++11

If I compile without -std=c++11 I get error: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions]
If I compile with -std=c++11 I get

Building library for inline-cpp-eg-0.1.0.0..
[2 of 2] Compiling Lib              ( src/Lib.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.1/build/Lib.o )
error: invalid argument '-std=c++11' not allowed with 'C/ObjC'
`gcc' failed in phase `C Compiler'. (Exit code: 1)

Strangely someFunc2 will compile in either case.

@stephenpascoe
Copy link
Author

I realise -std=c++11 is needed to compile the enum class statement because enum classes are a C++11 feature. So the question really is why does -std=c++11 cause compiling to fail when we use the $fun anti-quoter in someFunc but not when we compile someFunc2?

@stephenpascoe stephenpascoe changed the title Can't use function pointers in C++ code Can't use function pointers in C++11 code Jan 4, 2018
@stephenpascoe
Copy link
Author

After finding these related issues:

I tried building the source inside a docker container and it worked. The OSX compiler is more picky about what it allows.

@stephenpascoe
Copy link
Author

I can work around this with the custom Setup.hs below. Unfortunately stack ghci doesn't work but once you've built it you can comment out ghc-options and run stack ghci successfully.

import Distribution.Simple
import Distribution.Simple.Setup
import Distribution.Types.HookedBuildInfo
import Distribution.PackageDescription
import Distribution.Simple.LocalBuildInfo
import Data.List (dropWhile)

main = defaultMainWithHooks simpleUserHooks { buildHook = myBuildHook
                                            }

BuildHook :: PackageDescription -> LocalBuildInfo -> UserHooks -> BuildFlags -> IO ()
myBuildHook desc info hooks flags = (buildHook simpleUserHooks) (fixDescription desc) info hooks flags

-- Fix a PackageDescription to remove the -optc-std=c++11 option
fixDescription desc = desc { library = fmap fixLibrary (library desc) } where
  fixLibrary lib = lib { libBuildInfo = fixBuildInfo (libBuildInfo lib) }
  fixBuildInfo info = info { options = fixOptions (options info) }
  fixOptions options = fmap fixOption options
  fixOption (flavor, args) = (flavor, dropWhile ((==) "-optc-std=c++11") args)

@domenkozar
Copy link
Contributor

It's going to be a bit easier in GHC 8.8: https://gitlab.haskell.org/ghc/ghc/issues/16477

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants