autocxx icon indicating copy to clipboard operation
autocxx copied to clipboard

Overloaded function renaming might cause conflicts

Open hfiguiere opened this issue 1 year ago • 3 comments

Describe the bug

Overloaded function renaming might cause conflicts

To Reproduce

See https://github.com/google/autocxx/pull/1317

I have a class:

class Image {
public:
  static uint64_t byteSwap(uint64_t value, bool bSwap);
  static uint32_t byteSwap(uint32_t value, bool bSwap);
  static uint16_t byteSwap(uint16_t value, bool bSwap);
  static uint16_t byteSwap2(const DataBuf& buf, size_t offset, bool bSwap);
};

calling generate! on it will cause byteSwap2 to be generated twice. One for the overload, one for the actual byteSwap2.

pub unsafe fn byteSwap(value: u64, bSwap: bool) -> u64 { }
pub unsafe fn byteSwap1(value: u32, bSwap: bool) -> u32 { }
pub unsafe fn byteSwap2(value: u16, bSwap: bool) -> u16 { }
pub unsafe fn byteSwap2(buf: &root::Exiv2::DataBuf,
       offset: usize,
       bSwap: bool,
) -> u16 {}

This is because the renaming of the return u16 overload is byteSwap2 and there is an actual byteSwap2 function.

Expected behavior

Find a better renaming.

Or throw an error from the macro

Additional context

hfiguiere avatar Aug 04 '23 01:08 hfiguiere

Yeah, this isn't great and as the manual says, this all needs to be overhauled a bit. Meanwhile though I do certainly consider this a bug, and I'd accept a pull request for a temporary solution, e.g. if SomeOverloadedFunction2 already exists, then use a different suffix such as SomeOverloadedFunction_autocxx_overload2. I'm unlikely to get a chance to do this any time soon, but this might be a fairly easy fix so I'm going to mark it as Good First Issue in case someone else can help out.

adetaylor avatar Sep 01 '23 11:09 adetaylor

Closely related to #995

adetaylor avatar Sep 11 '23 11:09 adetaylor

Just sharing some random thoughts on overloaded functions. Would the following options be better?

  1. Generate macros for the overloaded functions?

    A potential problem I can see is overloads that have the same number of args but the args are of different types, like the three byteSwap functions mentioned above.

  2. Generate trait for the overloaded functions?

    What I am picturing is something like below. I guess a potential problem would be generating multiple traits of the same name.

struct Image;

pub trait ByteSwap<Args> {
    type Output;

    fn byte_swap(args: Args) -> Self::Output;
}

impl ByteSwap<(u64, bool)> for Image {
    type Output = u64;

    fn byte_swap(args: (u64, bool)) -> u64 { todo!() }
}


impl ByteSwap<(u32, bool)> for Image {
    type Output = u32;

    fn byte_swap(args: (u32, bool)) -> u32 { todo!() }
}

impl ByteSwap<(u16, bool)> for Image {
    type Output = u16;

    fn byte_swap(args: (u16, bool)) -> u16 { todo!() }
}

Or generate a trait for the args so that the trait doesn't need to be public

mod ffi {
    pub struct Image;
    
    impl Image {
        fn byte_swap<Args: ByteSwapArgs<Image>>(args: Args) -> Args::Output {
            ByteSwapArgs::<Image>::perform_byte_swap(args)
        }
    }
    
    trait ByteSwapArgs<T> {
        type Output;
    
        fn perform_byte_swap(self) -> Self::Output;
    }
    
    impl ByteSwapArgs<Image> for (u64, bool) {
        type Output = u64;
        
        fn perform_byte_swap(self) -> u64 { todo!() }
    }
    
    impl ByteSwapArgs<Image> for (u32, bool) {
        type Output = u32;
        
        fn perform_byte_swap(self) -> u32 { todo!() }
    }
    
    impl ByteSwapArgs<Image> for (u16, bool) {
        type Output = u16;
        
        fn perform_byte_swap(self) -> u16 { todo!() }
    }
}

minghuaw avatar Dec 22 '23 23:12 minghuaw